Latest from master - merge conflict resolution

This commit is contained in:
Gayathri
2017-04-12 09:03:54 -05:00
3494 changed files with 154303 additions and 26738 deletions

View File

@@ -15,6 +15,7 @@ import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.client.filter.GZIPContentEncodingFilter;
import com.sun.jersey.api.client.filter.LoggingFilter;
import com.sun.jersey.api.client.WebResource.Builder;
@@ -49,7 +50,7 @@ import {{invokerPackage}}.auth.OAuth;
{{>generatedAnnotation}}
public class ApiClient {
private Map<String, String> defaultHeaderMap = new HashMap<String, String>();
private String basePath = "{{basePath}}";
private String basePath = "{{{basePath}}}";
private boolean debugging = false;
private int connectionTimeout = 0;
@@ -102,6 +103,7 @@ public class ApiClient {
* Build the Client used to make HTTP requests with the latest settings,
* i.e. objectMapper and debugging.
* TODO: better to use the Builder Pattern?
* @return API client
*/
public ApiClient rebuildHttpClient() {
// Add the JSON serialization support to Jersey
@@ -109,6 +111,7 @@ public class ApiClient {
DefaultClientConfig conf = new DefaultClientConfig();
conf.getSingletons().add(jsonProvider);
Client client = Client.create(conf);
client.addFilter(new GZIPContentEncodingFilter({{#useGzipFeature}}true{{/useGzipFeature}}{{^useGzipFeature}}false{{/useGzipFeature}}));
if (debugging) {
client.addFilter(new LoggingFilter());
}
@@ -122,6 +125,7 @@ public class ApiClient {
* Note: If you make changes to the object mapper, remember to set it back via
* <code>setObjectMapper</code> in order to trigger HTTP client rebuilding.
* </p>
* @return Object mapper
*/
public ObjectMapper getObjectMapper() {
return objectMapper;
@@ -154,6 +158,7 @@ public class ApiClient {
/**
* Gets the status code of the previous request
* @return Status code
*/
public int getStatusCode() {
return statusCode;
@@ -161,6 +166,7 @@ public class ApiClient {
/**
* Gets the response headers of the previous request
* @return Response headers
*/
public Map<String, List<String>> getResponseHeaders() {
return responseHeaders;
@@ -168,6 +174,7 @@ public class ApiClient {
/**
* Get authentications (key: authentication name, value: authentication).
* @return Map of authentication
*/
public Map<String, Authentication> getAuthentications() {
return authentications;
@@ -185,6 +192,7 @@ public class ApiClient {
/**
* Helper method to set username for the first HTTP basic authentication.
* @param username Username
*/
public void setUsername(String username) {
for (Authentication auth : authentications.values()) {
@@ -198,6 +206,7 @@ public class ApiClient {
/**
* Helper method to set password for the first HTTP basic authentication.
* @param password Password
*/
public void setPassword(String password) {
for (Authentication auth : authentications.values()) {
@@ -211,6 +220,7 @@ public class ApiClient {
/**
* Helper method to set API key value for the first API key authentication.
* @param apiKey API key
*/
public void setApiKey(String apiKey) {
for (Authentication auth : authentications.values()) {
@@ -224,6 +234,7 @@ public class ApiClient {
/**
* Helper method to set API key prefix for the first API key authentication.
* @param apiKeyPrefix API key prefix
*/
public void setApiKeyPrefix(String apiKeyPrefix) {
for (Authentication auth : authentications.values()) {
@@ -237,6 +248,7 @@ public class ApiClient {
/**
* Helper method to set access token for the first OAuth2 authentication.
* @param accessToken Access token
*/
public void setAccessToken(String accessToken) {
for (Authentication auth : authentications.values()) {
@@ -250,6 +262,8 @@ public class ApiClient {
/**
* Set the User-Agent header's value (by adding to the default header map).
* @param userAgent User agent
* @return API client
*/
public ApiClient setUserAgent(String userAgent) {
addDefaultHeader("User-Agent", userAgent);
@@ -261,6 +275,7 @@ public class ApiClient {
*
* @param key The header's key
* @param value The header's value
* @return API client
*/
public ApiClient addDefaultHeader(String key, String value) {
defaultHeaderMap.put(key, value);
@@ -269,6 +284,7 @@ public class ApiClient {
/**
* Check that whether debugging is enabled for this API client.
* @return True if debugging is on
*/
public boolean isDebugging() {
return debugging;
@@ -278,6 +294,7 @@ public class ApiClient {
* Enable/disable debugging for this API client.
*
* @param debugging To enable (true) or disable (false) debugging
* @return API client
*/
public ApiClient setDebugging(boolean debugging) {
this.debugging = debugging;
@@ -288,6 +305,7 @@ public class ApiClient {
/**
* Connect timeout (in milliseconds).
* @return Connection timeout
*/
public int getConnectTimeout() {
return connectionTimeout;
@@ -297,6 +315,8 @@ public class ApiClient {
* Set the connect timeout (in milliseconds).
* A value of 0 means no timeout, otherwise values must be between 1 and
* {@link Integer#MAX_VALUE}.
* @param connectionTimeout Connection timeout in milliseconds
* @return API client
*/
public ApiClient setConnectTimeout(int connectionTimeout) {
this.connectionTimeout = connectionTimeout;
@@ -306,6 +326,7 @@ public class ApiClient {
/**
* Get the date format used to parse/format date parameters.
* @return Date format
*/
public DateFormat getDateFormat() {
return dateFormat;
@@ -313,6 +334,8 @@ public class ApiClient {
/**
* Set the date format used to parse/format date parameters.
* @param dateFormat Date format
* @return API client
*/
public ApiClient setDateFormat(DateFormat dateFormat) {
this.dateFormat = dateFormat;
@@ -325,6 +348,8 @@ public class ApiClient {
/**
* Parse the given string into Date object.
* @param str String
* @return Date
*/
public Date parseDate(String str) {
try {
@@ -336,6 +361,8 @@ public class ApiClient {
/**
* Format the given Date object into string.
* @param date Date
* @return Date in string format
*/
public String formatDate(Date date) {
return dateFormat.format(date);
@@ -343,6 +370,8 @@ public class ApiClient {
/**
* Format the given parameter object into string.
* @param param Object
* @return Object in string format
*/
public String parameterToString(Object param) {
if (param == null) {
@@ -353,7 +382,7 @@ public class ApiClient {
StringBuilder b = new StringBuilder();
for(Object o : (Collection<?>)param) {
if(b.length() > 0) {
b.append(",");
b.append(',');
}
b.append(String.valueOf(o));
}
@@ -364,15 +393,19 @@ public class ApiClient {
}
/*
Format to {@code Pair} objects.
*/
* Format to {@code Pair} objects.
* @param collectionFormat Collection format
* @param name Name
* @param value Value
* @return List of pair
*/
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;
Collection<?> valueCollection;
if (value instanceof Collection<?>) {
valueCollection = (Collection<?>) value;
} else {
@@ -385,10 +418,10 @@ public class ApiClient {
}
// get the collection format
collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv
String format = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv
// create the params based on the collection format
if (collectionFormat.equals("multi")) {
if ("multi".equals(format)) {
for (Object item : valueCollection) {
params.add(new Pair(name, parameterToString(item)));
}
@@ -398,13 +431,13 @@ public class ApiClient {
String delimiter = ",";
if (collectionFormat.equals("csv")) {
if ("csv".equals(format)) {
delimiter = ",";
} else if (collectionFormat.equals("ssv")) {
} else if ("ssv".equals(format)) {
delimiter = " ";
} else if (collectionFormat.equals("tsv")) {
} else if ("tsv".equals(format)) {
delimiter = "\t";
} else if (collectionFormat.equals("pipes")) {
} else if ("pipes".equals(format)) {
delimiter = "|";
}
@@ -425,9 +458,13 @@ public class ApiClient {
* application/json
* application/json; charset=UTF8
* APPLICATION/JSON
* application/vnd.company+json
* @param mime MIME
* @return True if MIME type is boolean
*/
public boolean isJsonMime(String mime) {
return mime != null && mime.matches("(?i)application\\/json(;.*)?");
String jsonMime = "(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$";
return mime != null && mime.matches(jsonMime);
}
/**
@@ -474,6 +511,8 @@ public class ApiClient {
/**
* Escape the given string to be used as URL query value.
* @param str String
* @return Escaped string
*/
public String escapeString(String str) {
try {
@@ -486,6 +525,11 @@ public class ApiClient {
/**
* Serialize the given Java object into string according the given
* Content-Type (only JSON is supported for now).
* @param obj Object
* @param contentType Content type
* @param formParams Form parameters
* @return Object
* @throws ApiException API exception
*/
public Object serialize(Object obj, String contentType, Map<String, Object> formParams) throws ApiException {
if (contentType.startsWith("multipart/form-data")) {
@@ -591,6 +635,7 @@ public class ApiClient {
/**
* Invoke API by sending HTTP request with the given options.
*
* @param <T> Type
* @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
@@ -600,7 +645,9 @@ public class ApiClient {
* @param accept The request's Accept header
* @param contentType The request's Content-Type header
* @param authNames The authentications to apply
* @param returnType Return type
* @return The response body in type of string
* @throws ApiException API exception
*/
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 {
@@ -639,6 +686,8 @@ public class ApiClient {
* Update query and header parameters based on authentication settings.
*
* @param authNames The authentications to apply
* @param queryParams Query parameters
* @param headerParams Header parameters
*/
private void updateParamsForAuth(String[] authNames, List<Pair> queryParams, Map<String, String> headerParams) {
for (String authName : authNames) {
@@ -650,6 +699,8 @@ public class ApiClient {
/**
* Encode the given form parameters as request body.
* @param formParams Form parameters
* @return HTTP form encoded parameters
*/
private String getXWWWFormUrlencodedParams(Map<String, Object> formParams) {
StringBuilder formParamBuilder = new StringBuilder();

View File

@@ -0,0 +1,27 @@
package {{invokerPackage}};
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ValidationException;
public class BeanValidationException extends ValidationException {
/**
*
*/
private static final long serialVersionUID = -5294733947409491364L;
Set<ConstraintViolation<Object>> violations;
public BeanValidationException(Set<ConstraintViolation<Object>> violations) {
this.violations = violations;
}
public Set<ConstraintViolation<Object>> getViolations() {
return violations;
}
public void setViolations(Set<ConstraintViolation<Object>> violations) {
this.violations = violations;
}
}

View File

@@ -130,7 +130,7 @@ Class | Method | HTTP request | Description
{{/isBasic}}
{{#isOAuth}}- **Type**: OAuth
- **Flow**: {{flow}}
- **Authorizatoin URL**: {{authorizationUrl}}
- **Authorization URL**: {{authorizationUrl}}
- **Scopes**: {{^scopes}}N/A{{/scopes}}
{{#scopes}} - {{scope}}: {{description}}
{{/scopes}}

View File

@@ -44,9 +44,13 @@ public class {{classname}} {
{{#operation}}
/**
* {{summary}}
* {{notes}}{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/allParams}}{{#returnType}}
* @return {{{returnType}}}{{/returnType}}
* {{notes}}
{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}
{{#returnType}}
* @return {{returnType}}
{{/returnType}}
* @throws ApiException if fails to make API call
*/
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
@@ -58,7 +62,7 @@ public class {{classname}} {
}
{{/required}}{{/allParams}}
// create path and map variables
String {{localVariablePrefix}}localVarPath = "{{{path}}}".replaceAll("\\{format\\}","json"){{#pathParams}}
String {{localVariablePrefix}}localVarPath = "{{{path}}}"{{#pathParams}}
.replaceAll("\\{" + "{{baseName}}" + "\\}", {{localVariablePrefix}}apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}};
// query params

View File

@@ -6,6 +6,7 @@ import {{invokerPackage}}.ApiException;
{{#imports}}import {{import}};
{{/imports}}
import org.junit.Test;
import org.junit.Ignore;
{{^fullJavaUtil}}
import java.util.ArrayList;
@@ -17,6 +18,7 @@ import java.util.Map;
/**
* API tests for {{classname}}
*/
@Ignore
public class {{classname}}Test {
private final {{classname}} api = new {{classname}}();
@@ -35,7 +37,7 @@ public class {{classname}}Test {
{{#allParams}}
{{{dataType}}} {{paramName}} = null;
{{/allParams}}
// {{#returnType}}{{{returnType}}} response = {{/returnType}}api.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{#returnType}}{{{returnType}}} response = {{/returnType}}api.{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
// TODO: test validations
}

View File

@@ -1,42 +1,4 @@
{{#required}}
@NotNull
{{/required}}
{{#pattern}}
@Pattern(regexp="{{pattern}}")
{{/pattern}}
{{#minLength}}
{{#maxLength}}
@Size(min={{minLength}},max={{maxLength}})
{{/maxLength}}
{{/minLength}}
{{#minLength}}
{{^maxLength}}
@Size(min={{minLength}})
{{/maxLength}}
{{/minLength}}
{{^minLength}}
{{#maxLength}}
@Size(max={{maxLength}})
{{/maxLength}}
{{/minLength}}
{{#minItems}}
{{#maxItems}}
@Size(min={{minItems}},max={{maxItems}})
{{/maxItems}}
{{/minItems}}
{{#minItems}}
{{^maxItems}}
@Size(min={{minItems}})
{{/maxItems}}
{{/minItems}}
{{^minItems}}
{{#maxItems}}
@Size(max={{maxItems}})
{{/maxItems}}
{{/minItems}}
{{#minimum}}
//@Min({{minimum}})
{{/minimum}}
{{#maximum}}
//@Max({{maximum}})
{{/maximum}}
{{>beanValidationCore}}

View File

@@ -0,0 +1,20 @@
{{#pattern}} @Pattern(regexp="{{pattern}}"){{/pattern}}{{!
minLength && maxLength set
}}{{#minLength}}{{#maxLength}} @Size(min={{minLength}},max={{maxLength}}){{/maxLength}}{{/minLength}}{{!
minLength set, maxLength not
}}{{#minLength}}{{^maxLength}} @Size(min={{minLength}}){{/maxLength}}{{/minLength}}{{!
minLength not set, maxLength set
}}{{^minLength}}{{#maxLength}} @Size(max={{maxLength}}){{/maxLength}}{{/minLength}}{{!
@Size: minItems && maxItems set
}}{{#minItems}}{{#maxItems}} @Size(min={{minItems}},max={{maxItems}}){{/maxItems}}{{/minItems}}{{!
@Size: minItems set, maxItems not
}}{{#minItems}}{{^maxItems}} @Size(min={{minItems}}){{/maxItems}}{{/minItems}}{{!
@Size: minItems not set && maxItems set
}}{{^minItems}}{{#maxItems}} @Size(max={{maxItems}}){{/maxItems}}{{/minItems}}{{!
check for integer or long / all others=decimal type with @Decimal*
isInteger set
}}{{#isInteger}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isInteger}}{{!
isLong set
}}{{#isLong}}{{#minimum}} @Min({{minimum}}){{/minimum}}{{#maximum}} @Max({{maximum}}){{/maximum}}{{/isLong}}{{!
Not Integer, not Long => we have a decimal value!
}}{{^isInteger}}{{^isLong}}{{#minimum}} @DecimalMin("{{minimum}}"){{/minimum}}{{#maximum}} @DecimalMax("{{maximum}}"){{/maximum}}{{/isLong}}{{/isInteger}}

View File

@@ -0,0 +1 @@
{{#required}} @NotNull{{/required}}{{>beanValidationCore}}

View File

@@ -45,17 +45,27 @@ public class ApiClient {
public ApiClient(String[] authNames) {
this();
for(String authName : authNames) { {{#hasAuthMethods}}
for(String authName : authNames) {
{{#hasAuthMethods}}
RequestInterceptor auth;
{{#authMethods}}if (authName == "{{name}}") { {{#isBasic}}
auth = new HttpBasicAuth();{{/isBasic}}{{#isApiKey}}
auth = new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}");{{/isApiKey}}{{#isOAuth}}
auth = new OAuth(OAuthFlow.{{flow}}, "{{authorizationUrl}}", "{{tokenUrl}}", "{{#scopes}}{{scope}}{{#hasMore}}, {{/hasMore}}{{/scopes}}");{{/isOAuth}}
{{#authMethods}}if ("{{name}}".equals(authName)) {
{{#isBasic}}
auth = new HttpBasicAuth();
{{/isBasic}}
{{#isApiKey}}
auth = new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}");
{{/isApiKey}}
{{#isOAuth}}
auth = new OAuth(OAuthFlow.{{flow}}, "{{authorizationUrl}}", "{{tokenUrl}}", "{{#scopes}}{{scope}}{{#hasMore}}, {{/hasMore}}{{/scopes}}");
{{/isOAuth}}
} else {{/authMethods}}{
throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");
}
addAuthorization(authName, auth);{{/hasAuthMethods}}{{^hasAuthMethods}}
throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");{{/hasAuthMethods}}
addAuthorization(authName, auth);
{{/hasAuthMethods}}
{{^hasAuthMethods}}
throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");
{{/hasAuthMethods}}
}
}
@@ -159,6 +169,9 @@ public class ApiClient {
* apiClient.setBasePath("http://localhost:8080");
* XYZApi api = apiClient.buildClient(XYZApi.class);
* XYZResponse response = api.someMethod(...);
* @param <T> Type
* @param clientClass Client class
* @return The Client
*/
public <T extends Api> T buildClient(Class<T> clientClass) {
return feignBuilder.target(clientClass, basePath);
@@ -196,7 +209,7 @@ public class ApiClient {
/**
* Helper method to configure the first api key found
* @param apiKey
* @param apiKey API key
*/
public void setApiKey(String apiKey) {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
@@ -211,8 +224,8 @@ public class ApiClient {
/**
* Helper method to configure the username/password for basic auth or password OAuth
* @param username
* @param password
* @param username Username
* @param password Password
*/
public void setCredentials(String username, String password) {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
@@ -232,7 +245,7 @@ public class ApiClient {
/**
* Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one)
* @return
* @return Token request builder
*/
public TokenRequestBuilder getTokenEndPoint() {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
@@ -246,7 +259,7 @@ public class ApiClient {
/**
* Helper method to configure authorization endpoint of the first oauth found in the apiAuthorizations (there should be only one)
* @return
* @return Authentication request builder
*/
public AuthenticationRequestBuilder getAuthorizationEndPoint() {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
@@ -260,8 +273,8 @@ public class ApiClient {
/**
* Helper method to pre-set the oauth access token of the first oauth found in the apiAuthorizations (there should be only one)
* @param accessToken
* @param expiresIn : validity period in seconds
* @param accessToken Access Token
* @param expiresIn Validity period in seconds
*/
public void setAccessToken(String accessToken, Long expiresIn) {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
@@ -275,9 +288,9 @@ public class ApiClient {
/**
* Helper method to configure the oauth accessCode/implicit flow parameters
* @param clientId
* @param clientSecret
* @param redirectURI
* @param clientId Client ID
* @param clientSecret Client secret
* @param redirectURI Redirect URI
*/
public void configureAuthorizationFlow(String clientId, String clientSecret, String redirectURI) {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
@@ -297,7 +310,7 @@ public class ApiClient {
/**
* Configures a listener which is notified when a new access token is received.
* @param accessTokenListener
* @param accessTokenListener Acesss token listener
*/
public void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
for(RequestInterceptor apiAuthorization : apiAuthorizations.values()) {
@@ -309,14 +322,19 @@ public class ApiClient {
}
}
/**
* Gets request interceptor based on authentication name
* @param authName Authentiation name
* @return Request Interceptor
*/
public RequestInterceptor getAuthorization(String authName) {
return apiAuthorizations.get(authName);
}
/**
* Adds an authorization to be used by the client
* @param authName
* @param authorization
* @param authName Authentication name
* @param authorization Request interceptor
*/
public void addAuthorization(String authName, RequestInterceptor authorization) {
if (apiAuthorizations.containsKey(authName)) {

View File

@@ -0,0 +1,86 @@
package {{invokerPackage}};
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Utilities to support Swagger encoding formats in Feign.
*/
public final class EncodingUtils {
/**
* Private constructor. Do not construct this class.
*/
private EncodingUtils() {}
/**
* <p>Encodes a collection of query parameters according to the Swagger
* collection format.</p>
*
* <p>Of the various collection formats defined by Swagger ("csv", "tsv",
* etc), Feign only natively supports "multi". This utility generates the
* other format types so it will be properly processed by Feign.</p>
*
* <p>Note, as part of reformatting, it URL encodes the parameters as
* well.</p>
* @param parameters The collection object to be formatted. This object will
* not be changed.
* @param collectionFormat The Swagger collection format (eg, "csv", "tsv",
* "pipes"). See the
* <a href="http://swagger.io/specification/#parameter-object-44">
* Swagger Spec</a> for more details.
* @return An object that will be correctly formatted by Feign.
*/
public static Object encodeCollection(Collection<?> parameters,
String collectionFormat) {
if (parameters == null) {
return parameters;
}
List<String> stringValues = new ArrayList<>(parameters.size());
for (Object parameter : parameters) {
// ignore null values (same behavior as Feign)
if (parameter != null) {
stringValues.add(encode(parameter));
}
}
// Feign natively handles single-element lists and the "multi" format.
if (stringValues.size() < 2 || "multi".equals(collectionFormat)) {
return stringValues;
}
// Otherwise return a formatted String
String[] stringArray = stringValues.toArray(new String[0]);
switch (collectionFormat) {
case "csv":
default:
return StringUtil.join(stringArray, ",");
case "ssv":
return StringUtil.join(stringArray, " ");
case "tsv":
return StringUtil.join(stringArray, "\t");
case "pipes":
return StringUtil.join(stringArray, "|");
}
}
/**
* URL encode a single query parameter.
* @param parameter The query parameter to encode. This object will not be
* changed.
* @return The URL encoded string representation of the parameter. If the
* parameter is null, returns null.
*/
public static String encode(Object parameter) {
if (parameter == null) {
return null;
}
try {
return URLEncoder.encode(parameter.toString(), "UTF-8");
} catch (UnsupportedEncodingException e) {
// Should never happen, UTF-8 is always supported
throw new RuntimeException(e);
}
}
}

View File

@@ -1,6 +1,7 @@
package {{package}};
import {{invokerPackage}}.ApiClient;
import {{invokerPackage}}.EncodingUtils;
{{#legacyDates}}
import {{invokerPackage}}.ParamExpander;
{{/legacyDates}}
@@ -23,8 +24,12 @@ public interface {{classname}} extends ApiClient.Api {
/**
* {{summary}}
* {{notes}}
{{#allParams}} * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}
{{#returnType}}
* @return {{returnType}}
{{/returnType}}
*/
@RequestLine("{{httpMethod}} {{{path}}}{{#hasQueryParams}}?{{/hasQueryParams}}{{#queryParams}}{{baseName}}={{=<% %>=}}{<%paramName%>}<%={{ }}=%>{{#hasMore}}&{{/hasMore}}{{/queryParams}}")
@Headers({
@@ -34,6 +39,59 @@ public interface {{classname}} extends ApiClient.Api {
{{/hasMore}}{{/headerParams}}
})
{{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{nickname}}({{#allParams}}{{^isBodyParam}}{{^legacyDates}}@Param("{{paramName}}") {{/legacyDates}}{{#legacyDates}}@Param(value="{{paramName}}", expander=ParamExpander.class) {{/legacyDates}}{{/isBodyParam}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
{{#hasQueryParams}}
/**
* {{summary}}
* {{notes}}
* Note, this is equivalent to the other <code>{{operationId}}</code> method,
* but with the query parameters collected into a single Map parameter. This
* is convenient for services with optional query parameters, especially when
* used with the {@link {{operationIdCamelCase}}QueryParams} class that allows for
* building up this map in a fluent style.
{{#allParams}}
{{^isQueryParam}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/isQueryParam}}
{{/allParams}}
* @param queryParams Map of query parameters as name-value pairs
* <p>The following elements may be specified in the query map:</p>
* <ul>
{{#queryParams}}
* <li>{{paramName}} - {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}</li>
{{/queryParams}}
* </ul>
{{#returnType}}
* @return {{returnType}}
{{/returnType}}
*/
@RequestLine("{{httpMethod}} {{{path}}}?{{#queryParams}}{{baseName}}={{=<% %>=}}{<%paramName%>}<%={{ }}=%>{{#hasMore}}&{{/hasMore}}{{/queryParams}}")
@Headers({
"Content-Type: {{vendorExtensions.x-contentType}}",
"Accept: {{vendorExtensions.x-accepts}}",{{#headerParams}}
"{{baseName}}: {{=<% %>=}}{<%paramName%>}<%={{ }}=%>"{{#hasMore}},
{{/hasMore}}{{/headerParams}}
})
{{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{nickname}}({{#allParams}}{{^isQueryParam}}{{^isBodyParam}}{{^legacyDates}}@Param("{{paramName}}") {{/legacyDates}}{{#legacyDates}}@Param(value="{{paramName}}", expander=ParamExpander.class) {{/legacyDates}}{{/isBodyParam}}{{{dataType}}} {{paramName}}, {{/isQueryParam}}{{/allParams}}@QueryMap(encoded=true) Map<String, Object> queryParams);
/**
* A convenience class for generating query parameters for the
* <code>{{operationId}}</code> method in a fluent style.
*/
public static class {{operationIdCamelCase}}QueryParams extends HashMap<String, Object> {
{{#queryParams}}
public {{operationIdCamelCase}}QueryParams {{paramName}}(final {{{dataType}}} value) {
{{#collectionFormat}}
put("{{baseName}}", EncodingUtils.encodeCollection(value, "{{collectionFormat}}"));
{{/collectionFormat}}
{{^collectionFormat}}
put("{{baseName}}", EncodingUtils.encode(value));
{{/collectionFormat}}
return this;
}
{{/queryParams}}
}
{{/hasQueryParams}}
{{/operation}}
{{/operations}}
}

View File

@@ -40,5 +40,31 @@ public class {{classname}}Test {
// TODO: test validations
}
{{#hasQueryParams}}
/**
* {{summary}}
*
* {{notes}}
*
* This tests the overload of the method that uses a Map for query parameters instead of
* listing them out individually.
*/
@Test
public void {{operationId}}TestQueryMap() {
{{#allParams}}
{{^isQueryParam}}
{{{dataType}}} {{paramName}} = null;
{{/isQueryParam}}
{{/allParams}}
{{classname}}.{{operationIdCamelCase}}QueryParams queryParams = new {{classname}}.{{operationIdCamelCase}}QueryParams()
{{#queryParams}}
.{{paramName}}(null){{^hasMore}};{{/hasMore}}
{{/queryParams}}
// {{#returnType}}{{{returnType}}} response = {{/returnType}}api.{{operationId}}({{#allParams}}{{^isQueryParam}}{{paramName}}, {{/isQueryParam}}{{/allParams}}queryParams);
// TODO: test validations
}
{{/hasQueryParams}}
{{/operation}}{{/operations}}
}

View File

@@ -95,9 +95,9 @@ if(hasProperty('target') && target == 'android') {
ext {
swagger_annotations_version = "1.5.9"
jackson_version = "2.7.5"
feign_version = "8.17.0"
feign_form_version = "2.0.2"
jackson_version = "2.8.7"
feign_version = "9.4.0"
feign_form_version = "2.1.0"
junit_version = "4.12"
oltu_version = "1.0.1"
}

View File

@@ -10,14 +10,14 @@ lazy val root = (project in file(".")).
resolvers += Resolver.mavenLocal,
libraryDependencies ++= Seq(
"io.swagger" % "swagger-annotations" % "1.5.9" % "compile",
"com.netflix.feign" % "feign-core" % "8.16.0" % "compile",
"com.netflix.feign" % "feign-jackson" % "8.17.0" % "compile",
"com.netflix.feign" % "feign-slf4j" % "8.16.0" % "compile",
"io.github.openfeign.form" % "feign-form" % "2.0.2" % "compile",
"com.fasterxml.jackson.core" % "jackson-core" % "2.7.5" % "compile",
"com.fasterxml.jackson.core" % "jackson-annotations" % "2.7.5" % "compile",
"com.fasterxml.jackson.core" % "jackson-databind" % "2.7.5" % "compile",
"com.fasterxml.jackson.datatype" % "jackson-datatype-{{^java8}}joda{{/java8}}{{#java8}}jsr310{{/java8}}" % "2.7.5" % "compile",
"com.netflix.feign" % "feign-core" % "9.4.0" % "compile",
"com.netflix.feign" % "feign-jackson" % "9.4.0" % "compile",
"com.netflix.feign" % "feign-slf4j" % "9.4.0" % "compile",
"io.github.openfeign.form" % "feign-form" % "2.1.0" % "compile",
"com.fasterxml.jackson.core" % "jackson-core" % "2.8.7" % "compile",
"com.fasterxml.jackson.core" % "jackson-annotations" % "2.8.7" % "compile",
"com.fasterxml.jackson.core" % "jackson-databind" % "2.8.7" % "compile",
"com.fasterxml.jackson.datatype" % "jackson-datatype-{{^java8}}joda{{/java8}}{{#java8}}jsr310{{/java8}}" % "2.8.7" % "compile",
"org.apache.oltu.oauth2" % "org.apache.oltu.oauth2.client" % "1.0.1" % "compile",
"com.brsanthu" % "migbase64" % "2.2" % "compile",
"junit" % "junit" % "4.12" % "test",

View File

@@ -6,15 +6,34 @@
<packaging>jar</packaging>
<name>{{artifactId}}</name>
<version>{{artifactVersion}}</version>
<url>{{artifactUrl}}</url>
<description>{{artifactDescription}}</description>
<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>
<connection>{{scmConnection}}</connection>
<developerConnection>{{scmDeveloperConnection}}</developerConnection>
<url>{{scmUrl}}</url>
</scm>
<prerequisites>
<maven>2.2.0</maven>
</prerequisites>
<licenses>
<license>
<name>{{licenseName}}</name>
<url>{{licenseUrl}}</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>{{developerName}}</name>
<email>{{developerEmail}}</email>
<organization>{{developerOrganization}}</organization>
<organizationUrl>{{developerOrganizationUrl}}</organizationUrl>
</developer>
</developers>
<build>
<plugins>
<plugin>
@@ -99,9 +118,55 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>sign-artifacts</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>io.swagger</groupId>
@@ -111,17 +176,17 @@
<!-- HTTP client: Netflix Feign -->
<dependency>
<groupId>com.netflix.feign</groupId>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
<version>${feign-version}</version>
</dependency>
<dependency>
<groupId>com.netflix.feign</groupId>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-jackson</artifactId>
<version>${feign-version}</version>
</dependency>
<dependency>
<groupId>com.netflix.feign</groupId>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-slf4j</artifactId>
<version>${feign-version}</version>
</dependency>
@@ -165,15 +230,27 @@
<version>${junit-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<version>3.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>1.7.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<java.version>{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<swagger-core-version>1.5.9</swagger-core-version>
<feign-version>8.17.0</feign-version>
<feign-form-version>2.0.2</feign-form-version>
<jackson-version>2.7.5</jackson-version>
<swagger-core-version>1.5.12</swagger-core-version>
<feign-version>9.4.0</feign-version>
<feign-form-version>2.1.0</feign-form-version>
<jackson-version>2.8.7</jackson-version>
<junit-version>4.12</junit-version>
<maven-plugin-version>1.0.0</maven-plugin-version>
<oltu-version>1.0.1</oltu-version>

View File

@@ -91,6 +91,7 @@ public class ApiClient {
/**
* Gets the JSON instance to do JSON serialization and deserialization.
* @return JSON
*/
public JSON getJSON() {
return json;
@@ -116,6 +117,7 @@ public class ApiClient {
/**
* Gets the status code of the previous request
* @return Status code
*/
public int getStatusCode() {
return statusCode;
@@ -123,6 +125,7 @@ public class ApiClient {
/**
* Gets the response headers of the previous request
* @return Response headers
*/
public Map<String, List<String>> getResponseHeaders() {
return responseHeaders;
@@ -130,6 +133,7 @@ public class ApiClient {
/**
* Get authentications (key: authentication name, value: authentication).
* @return Map of authentication object
*/
public Map<String, Authentication> getAuthentications() {
return authentications;
@@ -147,6 +151,7 @@ public class ApiClient {
/**
* Helper method to set username for the first HTTP basic authentication.
* @param username Username
*/
public void setUsername(String username) {
for (Authentication auth : authentications.values()) {
@@ -160,6 +165,7 @@ public class ApiClient {
/**
* Helper method to set password for the first HTTP basic authentication.
* @param password Password
*/
public void setPassword(String password) {
for (Authentication auth : authentications.values()) {
@@ -173,6 +179,7 @@ public class ApiClient {
/**
* Helper method to set API key value for the first API key authentication.
* @param apiKey API key
*/
public void setApiKey(String apiKey) {
for (Authentication auth : authentications.values()) {
@@ -186,6 +193,7 @@ public class ApiClient {
/**
* Helper method to set API key prefix for the first API key authentication.
* @param apiKeyPrefix API key prefix
*/
public void setApiKeyPrefix(String apiKeyPrefix) {
for (Authentication auth : authentications.values()) {
@@ -199,6 +207,7 @@ public class ApiClient {
/**
* Helper method to set access token for the first OAuth2 authentication.
* @param accessToken Access token
*/
public void setAccessToken(String accessToken) {
for (Authentication auth : authentications.values()) {
@@ -212,6 +221,8 @@ public class ApiClient {
/**
* Set the User-Agent header's value (by adding to the default header map).
* @param userAgent Http user agent
* @return API client
*/
public ApiClient setUserAgent(String userAgent) {
addDefaultHeader("User-Agent", userAgent);
@@ -223,6 +234,7 @@ public class ApiClient {
*
* @param key The header's key
* @param value The header's value
* @return API client
*/
public ApiClient addDefaultHeader(String key, String value) {
defaultHeaderMap.put(key, value);
@@ -231,6 +243,7 @@ public class ApiClient {
/**
* Check that whether debugging is enabled for this API client.
* @return True if debugging is switched on
*/
public boolean isDebugging() {
return debugging;
@@ -240,6 +253,7 @@ public class ApiClient {
* Enable/disable debugging for this API client.
*
* @param debugging To enable (true) or disable (false) debugging
* @return API client
*/
public ApiClient setDebugging(boolean debugging) {
this.debugging = debugging;
@@ -253,12 +267,17 @@ public class ApiClient {
* with file response. The default value is <code>null</code>, i.e. using
* the system's default tempopary folder.
*
* @see https://docs.oracle.com/javase/7/docs/api/java/io/File.html#createTempFile(java.lang.String,%20java.lang.String,%20java.io.File)
* @return Temp folder path
*/
public String getTempFolderPath() {
return tempFolderPath;
}
/**
* Set temp folder path
* @param tempFolderPath Temp folder path
* @return API client
*/
public ApiClient setTempFolderPath(String tempFolderPath) {
this.tempFolderPath = tempFolderPath;
return this;
@@ -266,6 +285,7 @@ public class ApiClient {
/**
* Connect timeout (in milliseconds).
* @return Connection timeout
*/
public int getConnectTimeout() {
return connectionTimeout;
@@ -275,6 +295,8 @@ public class ApiClient {
* Set the connect timeout (in milliseconds).
* A value of 0 means no timeout, otherwise values must be between 1 and
* {@link Integer#MAX_VALUE}.
* @param connectionTimeout Connection timeout in milliseconds
* @return API client
*/
public ApiClient setConnectTimeout(int connectionTimeout) {
this.connectionTimeout = connectionTimeout;
@@ -284,6 +306,7 @@ public class ApiClient {
/**
* Get the date format used to parse/format date parameters.
* @return Date format
*/
public DateFormat getDateFormat() {
return dateFormat;
@@ -291,6 +314,8 @@ public class ApiClient {
/**
* Set the date format used to parse/format date parameters.
* @param dateFormat Date format
* @return API client
*/
public ApiClient setDateFormat(DateFormat dateFormat) {
this.dateFormat = dateFormat;
@@ -301,6 +326,8 @@ public class ApiClient {
/**
* Parse the given string into Date object.
* @param str String
* @return Date
*/
public Date parseDate(String str) {
try {
@@ -312,6 +339,8 @@ public class ApiClient {
/**
* Format the given Date object into string.
* @param date Date
* @return Date in string format
*/
public String formatDate(Date date) {
return dateFormat.format(date);
@@ -319,6 +348,8 @@ public class ApiClient {
/**
* Format the given parameter object into string.
* @param param Object
* @return Object in string format
*/
public String parameterToString(Object param) {
if (param == null) {
@@ -329,7 +360,7 @@ public class ApiClient {
StringBuilder b = new StringBuilder();
for(Object o : (Collection)param) {
if(b.length() > 0) {
b.append(",");
b.append(',');
}
b.append(String.valueOf(o));
}
@@ -340,15 +371,19 @@ public class ApiClient {
}
/*
Format to {@code Pair} objects.
*/
* Format to {@code Pair} objects.
* @param collectionFormat Collection format
* @param name Name
* @param value Value
* @return List of pairs
*/
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;
Collection valueCollection;
if (value instanceof Collection) {
valueCollection = (Collection) value;
} else {
@@ -360,11 +395,11 @@ public class ApiClient {
return params;
}
// get the collection format
collectionFormat = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat); // default: csv
// get the collection format (default: csv)
String format = (collectionFormat == null || collectionFormat.isEmpty() ? "csv" : collectionFormat);
// create the params based on the collection format
if (collectionFormat.equals("multi")) {
if ("multi".equals(format)) {
for (Object item : valueCollection) {
params.add(new Pair(name, parameterToString(item)));
}
@@ -374,13 +409,13 @@ public class ApiClient {
String delimiter = ",";
if (collectionFormat.equals("csv")) {
if ("csv".equals(format)) {
delimiter = ",";
} else if (collectionFormat.equals("ssv")) {
} else if ("ssv".equals(format)) {
delimiter = " ";
} else if (collectionFormat.equals("tsv")) {
} else if ("tsv".equals(format)) {
delimiter = "\t";
} else if (collectionFormat.equals("pipes")) {
} else if ("pipes".equals(format)) {
delimiter = "|";
}
@@ -401,9 +436,13 @@ public class ApiClient {
* application/json
* application/json; charset=UTF8
* APPLICATION/JSON
* application/vnd.company+json
* @param mime MIME
* @return True if the MIME type is JSON
*/
public boolean isJsonMime(String mime) {
return mime != null && mime.matches("(?i)application\\/json(;.*)?");
String jsonMime = "(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$";
return mime != null && mime.matches(jsonMime);
}
/**
@@ -450,6 +489,8 @@ public class ApiClient {
/**
* Escape the given string to be used as URL query value.
* @param str String
* @return Escaped string
*/
public String escapeString(String str) {
try {
@@ -462,9 +503,14 @@ public class ApiClient {
/**
* Serialize the given Java object into string entity according the given
* Content-Type (only JSON is supported for now).
* @param obj Object
* @param formParams Form parameters
* @param contentType Context type
* @return Entity
* @throws ApiException API exception
*/
public Entity<?> serialize(Object obj, Map<String, Object> formParams, String contentType) throws ApiException {
Entity<?> entity = null;
Entity<?> entity;
if (contentType.startsWith("multipart/form-data")) {
MultiPart multiPart = new MultiPart();
for (Entry<String, Object> param: formParams.entrySet()) {
@@ -494,7 +540,13 @@ public class ApiClient {
/**
* Deserialize response body to Java object according to the Content-Type.
* @param <T> Type
* @param response Response
* @param returnType Return type
* @return Deserialize object
* @throws ApiException API exception
*/
@SuppressWarnings("unchecked")
public <T> T deserialize(Response response, GenericType<T> returnType) throws ApiException {
if (response == null || returnType == null) {
return null;
@@ -503,9 +555,8 @@ public class ApiClient {
if ("byte[]".equals(returnType.toString())) {
// Handle binary response (byte array).
return (T) response.readEntity(byte[].class);
} else if (returnType.equals(File.class)) {
} else if (returnType.getRawType() == File.class) {
// Handle file downloading.
@SuppressWarnings("unchecked")
T file = (T) downloadFileFromResponse(response);
return file;
}
@@ -522,6 +573,8 @@ public class ApiClient {
/**
* Download file from the given response.
* @param response Response
* @return File
* @throws ApiException If fail to read file content from response and write to disk
*/
public File downloadFileFromResponse(Response response) throws ApiException {
@@ -551,13 +604,13 @@ public class ApiClient {
filename = matcher.group(1);
}
String prefix = null;
String prefix;
String suffix = null;
if (filename == null) {
prefix = "download-";
suffix = "";
} else {
int pos = filename.lastIndexOf(".");
int pos = filename.lastIndexOf('.');
if (pos == -1) {
prefix = filename + "-";
} else {
@@ -578,6 +631,7 @@ public class ApiClient {
/**
* Invoke API by sending HTTP request with the given options.
*
* @param <T> Type
* @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
@@ -589,6 +643,7 @@ public class ApiClient {
* @param authNames The authentications to apply
* @param returnType The return type into which to deserialize the response
* @return The response body in type of string
* @throws ApiException API exception
*/
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);
@@ -607,16 +662,17 @@ public class ApiClient {
Invocation.Builder invocationBuilder = target.request().accept(accept);
for (String key : headerParams.keySet()) {
String value = headerParams.get(key);
for (Entry<String, String> entry : headerParams.entrySet()) {
String value = entry.getValue();
if (value != null) {
invocationBuilder = invocationBuilder.header(key, value);
invocationBuilder = invocationBuilder.header(entry.getKey(), value);
}
}
for (String key : defaultHeaderMap.keySet()) {
for (Entry<String, String> entry : defaultHeaderMap.entrySet()) {
String key = entry.getKey();
if (!headerParams.containsKey(key)) {
String value = defaultHeaderMap.get(key);
String value = entry.getValue();
if (value != null) {
invocationBuilder = invocationBuilder.header(key, value);
}
@@ -625,7 +681,7 @@ public class ApiClient {
Entity<?> entity = serialize(body, formParams, contentType);
Response response = null;
Response response;
if ("GET".equals(method)) {
response = invocationBuilder.get();
@@ -646,7 +702,7 @@ public class ApiClient {
if (response.getStatus() == Status.NO_CONTENT.getStatusCode()) {
return null;
} else if (response.getStatusInfo().getFamily().equals(Status.Family.SUCCESSFUL)) {
} else if (response.getStatusInfo().getFamily() == Status.Family.SUCCESSFUL) {
if (returnType == null)
return null;
else
@@ -672,6 +728,8 @@ public class ApiClient {
/**
* Build the Client used to make HTTP requests.
* @param debugging Debug setting
* @return Client
*/
private Client buildHttpClient(boolean debugging) {
final ClientConfig clientConfig = new ClientConfig();

View File

@@ -35,6 +35,7 @@ public class JSON implements ContextResolver<ObjectMapper> {
/**
* Set the date format for JSON (de)serialization with Date properties.
* @param dateFormat Date format
*/
public void setDateFormat(DateFormat dateFormat) {
mapper.setDateFormat(dateFormat);

View File

@@ -41,9 +41,13 @@ public class {{classname}} {
{{#operation}}
/**
* {{summary}}
* {{notes}}{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/allParams}}{{#returnType}}
* @return {{{returnType}}}{{/returnType}}
* {{notes}}
{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}
{{#returnType}}
* @return {{returnType}}
{{/returnType}}
* @throws ApiException if fails to make API call
*/
public {{#returnType}}{{{returnType}}} {{/returnType}}{{^returnType}}void {{/returnType}}{{operationId}}({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
@@ -55,7 +59,7 @@ public class {{classname}} {
}
{{/required}}{{/allParams}}
// create path and map variables
String {{localVariablePrefix}}localVarPath = "{{{path}}}".replaceAll("\\{format\\}","json"){{#pathParams}}
String {{localVariablePrefix}}localVarPath = "{{{path}}}"{{#pathParams}}
.replaceAll("\\{" + "{{baseName}}" + "\\}", {{localVariablePrefix}}apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}};
// query params

View File

@@ -6,15 +6,34 @@
<packaging>jar</packaging>
<name>{{artifactId}}</name>
<version>{{artifactVersion}}</version>
<url>{{artifactUrl}}</url>
<description>{{artifactDescription}}</description>
<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>
<connection>{{scmConnection}}</connection>
<developerConnection>{{scmDeveloperConnection}}</developerConnection>
<url>{{scmUrl}}</url>
</scm>
<prerequisites>
<maven>2.2.0</maven>
</prerequisites>
<licenses>
<license>
<name>{{licenseName}}</name>
<url>{{licenseUrl}}</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>{{developerName}}</name>
<email>{{developerEmail}}</email>
<organization>{{developerOrganization}}</organization>
<organizationUrl>{{developerOrganizationUrl}}</organizationUrl>
</developer>
</developers>
<build>
<plugins>
<plugin>
@@ -98,7 +117,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<version>3.6.1</version>
<configuration>
{{#java8}}
<source>1.8</source>
@@ -114,9 +133,55 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>sign-artifacts</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>io.swagger</groupId>
@@ -206,7 +271,7 @@
</dependency>
</dependencies>
<properties>
<swagger-core-version>1.5.9</swagger-core-version>
<swagger-core-version>1.5.12</swagger-core-version>
<jersey-version>2.22.2</jersey-version>
<jackson-version>2.7.5</jackson-version>
{{^java8}}

View File

@@ -128,6 +128,11 @@ public class ApiClient {
public ApiClient() {
httpClient = new OkHttpClient();
{{#useGzipFeature}}
// Enable gzip request compression
httpClient.interceptors().add(new GzipRequestInterceptor());
{{/useGzipFeature}}
verifyingSsl = true;
json = new JSON(this);
@@ -715,12 +720,13 @@ public class ApiClient {
* application/json
* application/json; charset=UTF8
* APPLICATION/JSON
*
* application/vnd.company+json
* @param mime MIME (Multipurpose Internet Mail Extensions)
* @return True if the given MIME is JSON, false otherwise.
*/
public boolean isJsonMime(String mime) {
return mime != null && mime.matches("(?i)application\\/json(;.*)?");
String jsonMime = "(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$";
return mime != null && mime.matches(jsonMime);
}
/**
@@ -1022,6 +1028,13 @@ public class ApiClient {
if (returnType == null || response.code() == 204) {
// returning null if the returnType is not defined,
// or the status code is 204 (No Content)
if (response.body() != null) {
try {
response.body().close();
} catch (IOException e) {
throw new ApiException(response.message(), e, response.code(), response.headers().toMultimap());
}
}
return null;
} else {
return deserialize(response, returnType);

View File

@@ -0,0 +1,70 @@
{{>licenseInfo}}
package {{invokerPackage}};
import com.squareup.okhttp.*;
import okio.Buffer;
import okio.BufferedSink;
import okio.GzipSink;
import okio.Okio;
import java.io.IOException;
/**
* Encodes request bodies using gzip.
*
* Taken from https://github.com/square/okhttp/issues/350
*/
class GzipRequestInterceptor implements Interceptor {
@Override public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) {
return chain.proceed(originalRequest);
}
Request compressedRequest = originalRequest.newBuilder()
.header("Content-Encoding", "gzip")
.method(originalRequest.method(), forceContentLength(gzip(originalRequest.body())))
.build();
return chain.proceed(compressedRequest);
}
private RequestBody forceContentLength(final RequestBody requestBody) throws IOException {
final Buffer buffer = new Buffer();
requestBody.writeTo(buffer);
return new RequestBody() {
@Override
public MediaType contentType() {
return requestBody.contentType();
}
@Override
public long contentLength() {
return buffer.size();
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
sink.write(buffer.snapshot());
}
};
}
private RequestBody gzip(final RequestBody body) {
return new RequestBody() {
@Override public MediaType contentType() {
return body.contentType();
}
@Override public long contentLength() {
return -1; // We don't know the compressed length in advance!
}
@Override public void writeTo(BufferedSink sink) throws IOException {
BufferedSink gzipSink = Okio.buffer(new GzipSink(sink));
body.writeTo(gzipSink);
gzipSink.close();
}
};
}
}

View File

@@ -172,14 +172,15 @@ class DateAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
*/
class DateTimeTypeAdapter extends TypeAdapter<DateTime> {
private final DateTimeFormatter formatter = ISODateTimeFormat.dateTime();
private final DateTimeFormatter parseFormatter = ISODateTimeFormat.dateOptionalTimeParser();
private final DateTimeFormatter printFormatter = ISODateTimeFormat.dateTime();
@Override
public void write(JsonWriter out, DateTime date) throws IOException {
if (date == null) {
out.nullValue();
} else {
out.value(formatter.print(date));
out.value(printFormatter.print(date));
}
}
@@ -191,7 +192,7 @@ class DateTimeTypeAdapter extends TypeAdapter<DateTime> {
return null;
default:
String date = in.nextString();
return formatter.parseDateTime(date);
return parseFormatter.parseDateTime(date);
}
}
}

View File

@@ -10,11 +10,27 @@ import {{invokerPackage}}.Configuration;
import {{invokerPackage}}.Pair;
import {{invokerPackage}}.ProgressRequestBody;
import {{invokerPackage}}.ProgressResponseBody;
{{#performBeanValidation}}
import {{invokerPackage}}.BeanValidationException;
{{/performBeanValidation}}
import com.google.gson.reflect.TypeToken;
import java.io.IOException;
{{#useBeanValidation}}
import javax.validation.constraints.*;
{{/useBeanValidation}}
{{#performBeanValidation}}
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;
import javax.validation.executable.ExecutableValidator;
import java.util.Set;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
{{/performBeanValidation}}
{{#imports}}import {{import}};
{{/imports}}
@@ -47,19 +63,20 @@ public class {{classname}} {
}
{{#operation}}
/* Build call for {{operationId}} */
private com.squareup.okhttp.Call {{operationId}}Call({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
/**
* Build call for {{operationId}}{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/allParams}}
* @param progressListener Progress listener
* @param progressRequestListener Progress request listener
* @return Call to execute
* @throws ApiException If fail to serialize the request body object
*/
public com.squareup.okhttp.Call {{operationId}}Call({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
Object {{localVariablePrefix}}localVarPostBody = {{#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 {{operationId}}(Async)");
}
{{/required}}{{/allParams}}
// create path and map variables
String {{localVariablePrefix}}localVarPath = "{{{path}}}".replaceAll("\\{format\\}","json"){{#pathParams}}
.replaceAll("\\{" + "{{baseName}}" + "\\}", {{localVariablePrefix}}apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}};
String {{localVariablePrefix}}localVarPath = "{{{path}}}"{{#pathParams}}
.replaceAll("\\{" + "{{baseName}}" + "\\}", {{localVariablePrefix}}apiClient.escapeString({{{paramName}}}.toString())){{/pathParams}};
{{javaUtilPrefix}}List<Pair> {{localVariablePrefix}}localVarQueryParams = new {{javaUtilPrefix}}ArrayList<Pair>();{{#queryParams}}
if ({{paramName}} != null)
@@ -99,6 +116,52 @@ public class {{classname}} {
String[] {{localVariablePrefix}}localVarAuthNames = new String[] { {{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}} };
return {{localVariablePrefix}}apiClient.buildCall({{localVariablePrefix}}localVarPath, "{{httpMethod}}", {{localVariablePrefix}}localVarQueryParams, {{localVariablePrefix}}localVarPostBody, {{localVariablePrefix}}localVarHeaderParams, {{localVariablePrefix}}localVarFormParams, {{localVariablePrefix}}localVarAuthNames, progressRequestListener);
}
@SuppressWarnings("rawtypes")
private com.squareup.okhttp.Call {{operationId}}ValidateBeforeCall({{#allParams}}{{{dataType}}} {{paramName}}, {{/allParams}}final ProgressResponseBody.ProgressListener progressListener, final ProgressRequestBody.ProgressRequestListener progressRequestListener) throws ApiException {
{{^performBeanValidation}}
{{#allParams}}{{#required}}
// verify the required parameter '{{paramName}}' is set
if ({{paramName}} == null) {
throw new ApiException("Missing the required parameter '{{paramName}}' when calling {{operationId}}(Async)");
}
{{/required}}{{/allParams}}
com.squareup.okhttp.Call {{localVariablePrefix}}call = {{operationId}}Call({{#allParams}}{{paramName}}, {{/allParams}}progressListener, progressRequestListener);
return {{localVariablePrefix}}call;
{{/performBeanValidation}}
{{#performBeanValidation}}
try {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
ExecutableValidator executableValidator = factory.getValidator().forExecutables();
Object[] parameterValues = { {{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}} };
Method method = this.getClass().getMethod("{{operationId}}WithHttpInfo"{{#allParams}}, {{#isListContainer}}java.util.List{{/isListContainer}}{{#isMapContainer}}java.util.Map{{/isMapContainer}}{{^isListContainer}}{{^isMapContainer}}{{{dataType}}}{{/isMapContainer}}{{/isListContainer}}.class{{/allParams}});
Set<ConstraintViolation<{{classname}}>> violations = executableValidator.validateParameters(this, method,
parameterValues);
if (violations.size() == 0) {
com.squareup.okhttp.Call {{localVariablePrefix}}call = {{operationId}}Call({{#allParams}}{{paramName}}, {{/allParams}}progressListener, progressRequestListener);
return {{localVariablePrefix}}call;
} else {
throw new BeanValidationException((Set) violations);
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
throw new ApiException(e.getMessage());
} catch (SecurityException e) {
e.printStackTrace();
throw new ApiException(e.getMessage());
}
{{/performBeanValidation}}
}
/**
@@ -120,8 +183,8 @@ public class {{classname}} {
* @return ApiResponse&lt;{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Void{{/returnType}}&gt;
* @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body
*/
public ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{operationId}}WithHttpInfo({{#allParams}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
com.squareup.okhttp.Call {{localVariablePrefix}}call = {{operationId}}Call({{#allParams}}{{paramName}}, {{/allParams}}null, null);
public ApiResponse<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{operationId}}WithHttpInfo({{#allParams}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) throws ApiException {
com.squareup.okhttp.Call {{localVariablePrefix}}call = {{operationId}}ValidateBeforeCall({{#allParams}}{{paramName}}, {{/allParams}}null, null);
{{#returnType}}Type {{localVariablePrefix}}localVarReturnType = new TypeToken<{{{returnType}}}>(){}.getType();
return {{localVariablePrefix}}apiClient.execute({{localVariablePrefix}}call, {{localVariablePrefix}}localVarReturnType);{{/returnType}}{{^returnType}}return {{localVariablePrefix}}apiClient.execute({{localVariablePrefix}}call);{{/returnType}}
}
@@ -155,7 +218,7 @@ public class {{classname}} {
};
}
com.squareup.okhttp.Call {{localVariablePrefix}}call = {{operationId}}Call({{#allParams}}{{paramName}}, {{/allParams}}progressListener, progressRequestListener);
com.squareup.okhttp.Call {{localVariablePrefix}}call = {{operationId}}ValidateBeforeCall({{#allParams}}{{paramName}}, {{/allParams}}progressListener, progressRequestListener);
{{#returnType}}Type {{localVariablePrefix}}localVarReturnType = new TypeToken<{{{returnType}}}>(){}.getType();
{{localVariablePrefix}}apiClient.executeAsync({{localVariablePrefix}}call, {{localVariablePrefix}}localVarReturnType, {{localVariablePrefix}}callback);{{/returnType}}{{^returnType}}{{localVariablePrefix}}apiClient.executeAsync({{localVariablePrefix}}call, {{localVariablePrefix}}callback);{{/returnType}}
return {{localVariablePrefix}}call;

View File

@@ -6,15 +6,34 @@
<packaging>jar</packaging>
<name>{{artifactId}}</name>
<version>{{artifactVersion}}</version>
<url>{{artifactUrl}}</url>
<description>{{artifactDescription}}</description>
<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>
<connection>{{scmConnection}}</connection>
<developerConnection>{{scmDeveloperConnection}}</developerConnection>
<url>{{scmUrl}}</url>
</scm>
<prerequisites>
<maven>2.2.0</maven>
</prerequisites>
<licenses>
<license>
<name>{{licenseName}}</name>
<url>{{licenseUrl}}</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>{{developerName}}</name>
<email>{{developerEmail}}</email>
<organization>{{developerOrganization}}</organization>
<organizationUrl>{{developerOrganizationUrl}}</organizationUrl>
</developer>
</developers>
<build>
<plugins>
<plugin>
@@ -100,9 +119,55 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>sign-artifacts</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>io.swagger</groupId>
@@ -131,7 +196,7 @@
<version>${jodatime-version}</version>
</dependency>
{{/java8}}
{{#useBeanValidation}}
{{#useBeanValidation}}
<!-- Bean Validation API support -->
<dependency>
<groupId>javax.validation</groupId>
@@ -139,8 +204,20 @@
<version>1.1.0.Final</version>
<scope>provided</scope>
</dependency>
{{/useBeanValidation}}
{{/useBeanValidation}}
{{#performBeanValidation}}
<!-- Bean Validation Impl. used to perform BeanValidation -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.2.Final</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
<version>2.2</version>
</dependency>
{{/performBeanValidation}}
<!-- test dependencies -->
<dependency>
<groupId>junit</groupId>
@@ -153,7 +230,7 @@
<java.version>{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<swagger-core-version>1.5.9</swagger-core-version>
<swagger-core-version>1.5.12</swagger-core-version>
<okhttp-version>2.7.5</okhttp-version>
<gson-version>2.6.2</gson-version>
<jodatime-version>2.9.3</jodatime-version>
@@ -161,4 +238,4 @@
<junit-version>4.12</junit-version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
</project>

View File

@@ -190,7 +190,11 @@
<version>${commons_io_version}</version>
</dependency>
{{/supportJava6}}
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<version>2.3.4.Final</version>
</dependency>
<!-- test dependencies -->
<dependency>
<groupId>junit</groupId>

View File

@@ -52,23 +52,32 @@ public class ApiClient {
public ApiClient(String[] authNames) {
this();
for(String authName : authNames) { {{#hasAuthMethods}}
for(String authName : authNames) {
{{#hasAuthMethods}}
Interceptor auth;
{{#authMethods}}if (authName == "{{name}}") { {{#isBasic}}
auth = new HttpBasicAuth();{{/isBasic}}{{#isApiKey}}
auth = new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}");{{/isApiKey}}{{#isOAuth}}
auth = new OAuth(OAuthFlow.{{flow}}, "{{authorizationUrl}}", "{{tokenUrl}}", "{{#scopes}}{{scope}}{{#hasMore}}, {{/hasMore}}{{/scopes}}");{{/isOAuth}}
{{#authMethods}}if ("{{name}}".equals(authName)) {
{{#isBasic}}
auth = new HttpBasicAuth();
{{/isBasic}}
{{#isApiKey}}
auth = new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}");{{/isApiKey}}
{{#isOAuth}}
auth = new OAuth(OAuthFlow.{{flow}}, "{{authorizationUrl}}", "{{tokenUrl}}", "{{#scopes}}{{scope}}{{#hasMore}}, {{/hasMore}}{{/scopes}}");
{{/isOAuth}}
} else {{/authMethods}}{
throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");
}
addAuthorization(authName, auth);{{/hasAuthMethods}}{{^hasAuthMethods}}
throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");{{/hasAuthMethods}}
addAuthorization(authName, auth);
{{/hasAuthMethods}}
{{^hasAuthMethods}}
throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");
{{/hasAuthMethods}}
}
}
/**
* Basic constructor for single auth name
* @param authName
* @param authName Authentication name
*/
public ApiClient(String authName) {
this(new String[]{authName});
@@ -76,8 +85,8 @@ public class ApiClient {
/**
* Helper constructor for single api key
* @param authName
* @param apiKey
* @param authName Authentication name
* @param apiKey API key
*/
public ApiClient(String authName, String apiKey) {
this(authName);
@@ -86,9 +95,9 @@ public class ApiClient {
/**
* Helper constructor for single basic auth or password oauth2
* @param authName
* @param username
* @param password
* @param authName Authentication name
* @param username Username
* @param password Password
*/
public ApiClient(String authName, String username, String password) {
this(authName);
@@ -97,11 +106,11 @@ public class ApiClient {
/**
* Helper constructor for single password oauth2
* @param authName
* @param clientId
* @param secret
* @param username
* @param password
* @param authName Authentication name
* @param clientId Client ID
* @param secret Client secret
* @param username Username
* @param password Password
*/
public ApiClient(String authName, String clientId, String secret, String username, String password) {
this(authName);
@@ -135,7 +144,7 @@ public class ApiClient {
/**
* Helper method to configure the first api key found
* @param apiKey
* @param apiKey API key
*/
private void setApiKey(String apiKey) {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
@@ -149,8 +158,8 @@ public class ApiClient {
/**
* Helper method to configure the username/password for basic auth or password oauth
* @param username
* @param password
* @param username Username
* @param password Password
*/
private void setCredentials(String username, String password) {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
@@ -169,7 +178,7 @@ public class ApiClient {
/**
* Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one)
* @return
* @return Token request builder
*/
public TokenRequestBuilder getTokenEndPoint() {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
@@ -183,7 +192,7 @@ public class ApiClient {
/**
* Helper method to configure authorization endpoint of the first oauth found in the apiAuthorizations (there should be only one)
* @return
* @return Authentication request builder
*/
public AuthenticationRequestBuilder getAuthorizationEndPoint() {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
@@ -197,7 +206,7 @@ public class ApiClient {
/**
* Helper method to pre-set the oauth access token of the first oauth found in the apiAuthorizations (there should be only one)
* @param accessToken
* @param accessToken Access token
*/
public void setAccessToken(String accessToken) {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
@@ -211,9 +220,9 @@ public class ApiClient {
/**
* Helper method to configure the oauth accessCode/implicit flow parameters
* @param clientId
* @param clientSecret
* @param redirectURI
* @param clientId Client ID
* @param clientSecret Client secret
* @param redirectURI Redirect URI
*/
public void configureAuthorizationFlow(String clientId, String clientSecret, String redirectURI) {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
@@ -233,7 +242,7 @@ public class ApiClient {
/**
* Configures a listener which is notified when a new access token is received.
* @param accessTokenListener
* @param accessTokenListener Access token listener
*/
public void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
@@ -247,8 +256,8 @@ public class ApiClient {
/**
* Adds an authorization to be used by the client
* @param authName
* @param authorization
* @param authName Authentication name
* @param authorization Authorization
*/
public void addAuthorization(String authName, Interceptor authorization) {
if (apiAuthorizations.containsKey(authName)) {
@@ -286,7 +295,7 @@ public class ApiClient {
/**
* Clones the okClient given in parameter, adds the auth interceptors and uses it to configure the RestAdapter
* @param okClient
* @param okClient OkHttp client
*/
public void configureFromOkclient(OkHttpClient okClient) {
OkHttpClient clone = okClient.clone();
@@ -354,14 +363,15 @@ class GsonConverterWrapper implements Converter {
*/
class DateTimeTypeAdapter extends TypeAdapter<DateTime> {
private final DateTimeFormatter formatter = ISODateTimeFormat.dateTime();
private final DateTimeFormatter parseFormatter = ISODateTimeFormat.dateOptionalTimeParser();
private final DateTimeFormatter printFormatter = ISODateTimeFormat.dateTime();
@Override
public void write(JsonWriter out, DateTime date) throws IOException {
if (date == null) {
out.nullValue();
} else {
out.value(formatter.print(date));
out.value(printFormatter.print(date));
}
}
@@ -373,7 +383,7 @@ class DateTimeTypeAdapter extends TypeAdapter<DateTime> {
return null;
default:
String date = in.nextString();
return formatter.parseDateTime(date);
return parseFormatter.parseDateTime(date);
}
}
}

View File

@@ -23,12 +23,16 @@ public interface {{classname}} {
* {{summary}}
* Sync method
* {{notes}}
{{#allParams}} * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}
{{#returnType}}
* @return {{returnType}}
{{/returnType}}
*/
{{#formParams}}{{#-first}}
{{#isMultipart}}@retrofit.http.Multipart{{/isMultipart}}{{^isMultipart}}@retrofit.http.FormUrlEncoded{{/isMultipart}}{{/-first}}{{/formParams}}
@{{httpMethod}}("{{path}}")
@{{httpMethod}}("{{{path}}}")
{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}} {{operationId}}({{^allParams}});{{/allParams}}
{{#allParams}}{{>libraries/retrofit/queryParams}}{{>libraries/retrofit/pathParams}}{{>libraries/retrofit/headerParams}}{{>libraries/retrofit/bodyParams}}{{>libraries/retrofit/formParams}}{{#hasMore}}, {{/hasMore}}{{^hasMore}}
);{{/hasMore}}{{/allParams}}
@@ -36,13 +40,14 @@ public interface {{classname}} {
/**
* {{summary}}
* Async method
{{#allParams}} * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}} * @param cb callback method
* @return void
{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}
* @param cb callback method
*/
{{#formParams}}{{#-first}}
{{#isMultipart}}@retrofit.http.Multipart{{/isMultipart}}{{^isMultipart}}@retrofit.http.FormUrlEncoded{{/isMultipart}}{{/-first}}{{/formParams}}
@{{httpMethod}}("{{path}}")
@{{httpMethod}}("{{{path}}}")
void {{operationId}}(
{{#allParams}}{{>libraries/retrofit/queryParams}}{{>libraries/retrofit/pathParams}}{{>libraries/retrofit/headerParams}}{{>libraries/retrofit/bodyParams}}{{>libraries/retrofit/formParams}}, {{/allParams}}Callback<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}> cb
);

View File

@@ -132,7 +132,7 @@ public class OAuth implements Interceptor {
if (accessTokenListener != null) {
accessTokenListener.notify((BasicOAuthToken) accessTokenResponse.getOAuthToken());
}
return getAccessToken().equals(requestAccessToken);
return !getAccessToken().equals(requestAccessToken);
} else {
return false;
}

View File

@@ -6,15 +6,34 @@
<packaging>jar</packaging>
<name>{{artifactId}}</name>
<version>{{artifactVersion}}</version>
<url>{{artifactUrl}}</url>
<description>{{artifactDescription}}</description>
<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>
<connection>{{scmConnection}}</connection>
<developerConnection>{{scmDeveloperConnection}}</developerConnection>
<url>{{scmUrl}}</url>
</scm>
<prerequisites>
<maven>2.2.0</maven>
</prerequisites>
<licenses>
<license>
<name>{{licenseName}}</name>
<url>{{licenseUrl}}</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>{{developerName}}</name>
<email>{{developerEmail}}</email>
<organization>{{developerOrganization}}</organization>
<organizationUrl>{{developerOrganizationUrl}}</organizationUrl>
</developer>
</developers>
<build>
<plugins>
<plugin>
@@ -98,7 +117,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<version>3.6.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
@@ -108,9 +127,55 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>sign-artifacts</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>io.swagger</groupId>
@@ -147,7 +212,7 @@
</dependency>
</dependencies>
<properties>
<swagger-core-version>1.5.9</swagger-core-version>
<swagger-core-version>1.5.12</swagger-core-version>
<retrofit-version>1.9.0</retrofit-version>
<okhttp-version>2.7.5</okhttp-version>
<jodatime-version>2.9.3</jodatime-version>

View File

@@ -22,7 +22,12 @@ import java.time.format.DateTimeFormatter;
{{/java8}}
import retrofit2.Converter;
import retrofit2.Retrofit;
{{#useRxJava}}import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;{{/useRxJava}}
{{#useRxJava}}
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
{{/useRxJava}}
{{#useRxJava2}}
import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
{{/useRxJava2}}
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;
@@ -37,281 +42,293 @@ import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import {{invokerPackage}}.auth.HttpBasicAuth;
import {{invokerPackage}}.auth.ApiKeyAuth;
import {{invokerPackage}}.auth.OAuth;
import {{invokerPackage}}.auth.OAuth.AccessTokenListener;
import {{invokerPackage}}.auth.OAuthFlow;
public class ApiClient {
private Map<String, Interceptor> apiAuthorizations;
private OkHttpClient.Builder okBuilder;
private Retrofit.Builder adapterBuilder;
private Map<String, Interceptor> apiAuthorizations;
private OkHttpClient.Builder okBuilder;
private Retrofit.Builder adapterBuilder;
public ApiClient() {
apiAuthorizations = new LinkedHashMap<String, Interceptor>();
createDefaultAdapter();
public ApiClient() {
apiAuthorizations = new LinkedHashMap<String, Interceptor>();
createDefaultAdapter();
}
public ApiClient(String[] authNames) {
this();
for(String authName : authNames) {
{{#hasAuthMethods}}
Interceptor auth;
{{#authMethods}}if ("{{name}}".equals(authName)) {
{{#isBasic}}
auth = new HttpBasicAuth();
{{/isBasic}}
{{#isApiKey}}
auth = new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}");
{{/isApiKey}}
{{#isOAuth}}
auth = new OAuth(OAuthFlow.{{flow}}, "{{authorizationUrl}}", "{{tokenUrl}}", "{{#scopes}}{{scope}}{{#hasMore}}, {{/hasMore}}{{/scopes}}");
{{/isOAuth}}
} else {{/authMethods}}{
throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");
}
addAuthorization(authName, auth);
{{/hasAuthMethods}}
{{^hasAuthMethods}}
throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");
{{/hasAuthMethods}}
}
}
public ApiClient(String[] authNames) {
this();
for(String authName : authNames) { {{#hasAuthMethods}}
Interceptor auth;
{{#authMethods}}if (authName == "{{name}}") { {{#isBasic}}
auth = new HttpBasicAuth();{{/isBasic}}{{#isApiKey}}
auth = new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}");{{/isApiKey}}{{#isOAuth}}
auth = new OAuth(OAuthFlow.{{flow}}, "{{authorizationUrl}}", "{{tokenUrl}}", "{{#scopes}}{{scope}}{{#hasMore}}, {{/hasMore}}{{/scopes}}");{{/isOAuth}}
} else {{/authMethods}}{
throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");
}
addAuthorization(authName, auth);{{/hasAuthMethods}}{{^hasAuthMethods}}
throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");{{/hasAuthMethods}}
}
/**
* Basic constructor for single auth name
* @param authName Authentication name
*/
public ApiClient(String authName) {
this(new String[]{authName});
}
/**
* Helper constructor for single api key
* @param authName Authentication name
* @param apiKey API key
*/
public ApiClient(String authName, String apiKey) {
this(authName);
this.setApiKey(apiKey);
}
/**
* Helper constructor for single basic auth or password oauth2
* @param authName Authentication name
* @param username Username
* @param password Password
*/
public ApiClient(String authName, String username, String password) {
this(authName);
this.setCredentials(username, password);
}
/**
* Helper constructor for single password oauth2
* @param authName Authentication name
* @param clientId Client ID
* @param secret Client Secret
* @param username Username
* @param password Password
*/
public ApiClient(String authName, String clientId, String secret, String username, String password) {
this(authName);
this.getTokenEndPoint()
.setClientId(clientId)
.setClientSecret(secret)
.setUsername(username)
.setPassword(password);
}
public void createDefaultAdapter() {
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
{{^java8}}
.registerTypeAdapter(DateTime.class, new DateTimeTypeAdapter())
{{/java8}}
{{#java8}}
.registerTypeAdapter(OffsetDateTime.class, new OffsetDateTimeTypeAdapter())
{{/java8}}
.registerTypeAdapter(LocalDate.class, new LocalDateTypeAdapter())
.create();
okBuilder = new OkHttpClient.Builder();
String baseUrl = "{{{basePath}}}";
if(!baseUrl.endsWith("/"))
baseUrl = baseUrl + "/";
adapterBuilder = new Retrofit
.Builder()
.baseUrl(baseUrl)
{{#useRxJava}}
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
{{/useRxJava}}
{{#useRxJava2}}
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
{{/useRxJava2}}
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonCustomConverterFactory.create(gson));
}
public <S> S createService(Class<S> serviceClass) {
return adapterBuilder
.client(okBuilder.build())
.build()
.create(serviceClass);
}
/**
* Helper method to configure the first api key found
* @param apiKey API key
*/
private void setApiKey(String apiKey) {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof ApiKeyAuth) {
ApiKeyAuth keyAuth = (ApiKeyAuth) apiAuthorization;
keyAuth.setApiKey(apiKey);
return;
}
}
}
/**
* Basic constructor for single auth name
* @param authName Authentication name
*/
public ApiClient(String authName) {
this(new String[]{authName});
/**
* Helper method to configure the username/password for basic auth or password oauth
* @param username Username
* @param password Password
*/
private void setCredentials(String username, String password) {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof HttpBasicAuth) {
HttpBasicAuth basicAuth = (HttpBasicAuth) apiAuthorization;
basicAuth.setCredentials(username, password);
return;
}
if (apiAuthorization instanceof OAuth) {
OAuth oauth = (OAuth) apiAuthorization;
oauth.getTokenRequestBuilder().setUsername(username).setPassword(password);
return;
}
}
}
/**
* Helper constructor for single api key
* @param authName Authentication name
* @param apiKey API key
*/
public ApiClient(String authName, String apiKey) {
this(authName);
this.setApiKey(apiKey);
/**
* Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one)
* @return Token request builder
*/
public TokenRequestBuilder getTokenEndPoint() {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof OAuth) {
OAuth oauth = (OAuth) apiAuthorization;
return oauth.getTokenRequestBuilder();
}
}
return null;
}
/**
* Helper constructor for single basic auth or password oauth2
* @param authName Authentication name
* @param username Username
* @param password Password
*/
public ApiClient(String authName, String username, String password) {
this(authName);
this.setCredentials(username, password);
/**
* Helper method to configure authorization endpoint of the first oauth found in the apiAuthorizations (there should be only one)
* @return Authentication request builder
*/
public AuthenticationRequestBuilder getAuthorizationEndPoint() {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof OAuth) {
OAuth oauth = (OAuth) apiAuthorization;
return oauth.getAuthenticationRequestBuilder();
}
}
return null;
}
/**
* Helper constructor for single password oauth2
* @param authName Authentication name
* @param clientId Client ID
* @param secret Client Secret
* @param username Username
* @param password Password
*/
public ApiClient(String authName, String clientId, String secret, String username, String password) {
this(authName);
this.getTokenEndPoint()
.setClientId(clientId)
.setClientSecret(secret)
.setUsername(username)
.setPassword(password);
/**
* Helper method to pre-set the oauth access token of the first oauth found in the apiAuthorizations (there should be only one)
* @param accessToken Access token
*/
public void setAccessToken(String accessToken) {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof OAuth) {
OAuth oauth = (OAuth) apiAuthorization;
oauth.setAccessToken(accessToken);
return;
}
}
}
public void createDefaultAdapter() {
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
{{^java8}}
.registerTypeAdapter(DateTime.class, new DateTimeTypeAdapter())
{{/java8}}
{{#java8}}
.registerTypeAdapter(OffsetDateTime.class, new OffsetDateTimeTypeAdapter())
{{/java8}}
.registerTypeAdapter(LocalDate.class, new LocalDateTypeAdapter())
.create();
okBuilder = new OkHttpClient.Builder();
String baseUrl = "{{{basePath}}}";
if(!baseUrl.endsWith("/"))
baseUrl = baseUrl + "/";
adapterBuilder = new Retrofit
.Builder()
.baseUrl(baseUrl)
{{#useRxJava}}.addCallAdapterFactory(RxJavaCallAdapterFactory.create()){{/useRxJava}}
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonCustomConverterFactory.create(gson));
/**
* Helper method to configure the oauth accessCode/implicit flow parameters
* @param clientId Client ID
* @param clientSecret Client secret
* @param redirectURI Redirect URI
*/
public void configureAuthorizationFlow(String clientId, String clientSecret, String redirectURI) {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof OAuth) {
OAuth oauth = (OAuth) apiAuthorization;
oauth.getTokenRequestBuilder()
.setClientId(clientId)
.setClientSecret(clientSecret)
.setRedirectURI(redirectURI);
oauth.getAuthenticationRequestBuilder()
.setClientId(clientId)
.setRedirectURI(redirectURI);
return;
}
}
}
public <S> S createService(Class<S> serviceClass) {
return adapterBuilder
.client(okBuilder.build())
.build()
.create(serviceClass);
/**
* Configures a listener which is notified when a new access token is received.
* @param accessTokenListener Access token listener
*/
public void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof OAuth) {
OAuth oauth = (OAuth) apiAuthorization;
oauth.registerAccessTokenListener(accessTokenListener);
return;
}
}
}
/**
* Helper method to configure the first api key found
* @param apiKey API key
*/
private void setApiKey(String apiKey) {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof ApiKeyAuth) {
ApiKeyAuth keyAuth = (ApiKeyAuth) apiAuthorization;
keyAuth.setApiKey(apiKey);
return;
}
}
/**
* Adds an authorization to be used by the client
* @param authName Authentication name
* @param authorization Authorization interceptor
*/
public void addAuthorization(String authName, Interceptor authorization) {
if (apiAuthorizations.containsKey(authName)) {
throw new RuntimeException("auth name \"" + authName + "\" already in api authorizations");
}
apiAuthorizations.put(authName, authorization);
okBuilder.addInterceptor(authorization);
}
/**
* Helper method to configure the username/password for basic auth or password oauth
* @param username Username
* @param password Password
*/
private void setCredentials(String username, String password) {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof HttpBasicAuth) {
HttpBasicAuth basicAuth = (HttpBasicAuth) apiAuthorization;
basicAuth.setCredentials(username, password);
return;
}
if (apiAuthorization instanceof OAuth) {
OAuth oauth = (OAuth) apiAuthorization;
oauth.getTokenRequestBuilder().setUsername(username).setPassword(password);
return;
}
}
public Map<String, Interceptor> getApiAuthorizations() {
return apiAuthorizations;
}
public void setApiAuthorizations(Map<String, Interceptor> apiAuthorizations) {
this.apiAuthorizations = apiAuthorizations;
}
public Retrofit.Builder getAdapterBuilder() {
return adapterBuilder;
}
public void setAdapterBuilder(Retrofit.Builder adapterBuilder) {
this.adapterBuilder = adapterBuilder;
}
public OkHttpClient.Builder getOkBuilder() {
return okBuilder;
}
public void addAuthsToOkBuilder(OkHttpClient.Builder okBuilder) {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
okBuilder.addInterceptor(apiAuthorization);
}
}
/**
* Helper method to configure the token endpoint of the first oauth found in the apiAuthorizations (there should be only one)
* @return Token request builder
*/
public TokenRequestBuilder getTokenEndPoint() {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof OAuth) {
OAuth oauth = (OAuth) apiAuthorization;
return oauth.getTokenRequestBuilder();
}
}
return null;
}
/**
* Helper method to configure authorization endpoint of the first oauth found in the apiAuthorizations (there should be only one)
* @return Authentication request builder
*/
public AuthenticationRequestBuilder getAuthorizationEndPoint() {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof OAuth) {
OAuth oauth = (OAuth) apiAuthorization;
return oauth.getAuthenticationRequestBuilder();
}
}
return null;
}
/**
* Helper method to pre-set the oauth access token of the first oauth found in the apiAuthorizations (there should be only one)
* @param accessToken Access token
*/
public void setAccessToken(String accessToken) {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof OAuth) {
OAuth oauth = (OAuth) apiAuthorization;
oauth.setAccessToken(accessToken);
return;
}
}
}
/**
* Helper method to configure the oauth accessCode/implicit flow parameters
* @param clientId Client ID
* @param clientSecret Client secret
* @param redirectURI Redirect URI
*/
public void configureAuthorizationFlow(String clientId, String clientSecret, String redirectURI) {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof OAuth) {
OAuth oauth = (OAuth) apiAuthorization;
oauth.getTokenRequestBuilder()
.setClientId(clientId)
.setClientSecret(clientSecret)
.setRedirectURI(redirectURI);
oauth.getAuthenticationRequestBuilder()
.setClientId(clientId)
.setRedirectURI(redirectURI);
return;
}
}
}
/**
* Configures a listener which is notified when a new access token is received.
* @param accessTokenListener Access token listener
*/
public void registerAccessTokenListener(AccessTokenListener accessTokenListener) {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
if (apiAuthorization instanceof OAuth) {
OAuth oauth = (OAuth) apiAuthorization;
oauth.registerAccessTokenListener(accessTokenListener);
return;
}
}
}
/**
* Adds an authorization to be used by the client
* @param authName Authentication name
* @param authorization Authorization interceptor
*/
public void addAuthorization(String authName, Interceptor authorization) {
if (apiAuthorizations.containsKey(authName)) {
throw new RuntimeException("auth name \"" + authName + "\" already in api authorizations");
}
apiAuthorizations.put(authName, authorization);
okBuilder.addInterceptor(authorization);
}
public Map<String, Interceptor> getApiAuthorizations() {
return apiAuthorizations;
}
public void setApiAuthorizations(Map<String, Interceptor> apiAuthorizations) {
this.apiAuthorizations = apiAuthorizations;
}
public Retrofit.Builder getAdapterBuilder() {
return adapterBuilder;
}
public void setAdapterBuilder(Retrofit.Builder adapterBuilder) {
this.adapterBuilder = adapterBuilder;
}
public OkHttpClient.Builder getOkBuilder() {
return okBuilder;
}
public void addAuthsToOkBuilder(OkHttpClient.Builder okBuilder) {
for(Interceptor apiAuthorization : apiAuthorizations.values()) {
okBuilder.addInterceptor(apiAuthorization);
}
}
/**
* Clones the okBuilder given in parameter, adds the auth interceptors and uses it to configure the Retrofit
* @param okClient An instance of OK HTTP client
*/
public void configureFromOkclient(OkHttpClient okClient) {
this.okBuilder = okClient.newBuilder();
addAuthsToOkBuilder(this.okBuilder);
}
/**
* Clones the okBuilder given in parameter, adds the auth interceptors and uses it to configure the Retrofit
* @param okClient An instance of OK HTTP client
*/
public void configureFromOkclient(OkHttpClient okClient) {
this.okBuilder = okClient.newBuilder();
addAuthsToOkBuilder(this.okBuilder);
}
}
/**
@@ -320,52 +337,54 @@ public class ApiClient {
* expected type is String, then just return the body string.
*/
class GsonResponseBodyConverterToString<T> implements Converter<ResponseBody, T> {
private final Gson gson;
private final Type type;
GsonResponseBodyConverterToString(Gson gson, Type type) {
this.gson = gson;
this.type = type;
}
private final Gson gson;
private final Type type;
@Override public T convert(ResponseBody value) throws IOException {
String returned = value.string();
try {
return gson.fromJson(returned, type);
}
catch (JsonParseException e) {
return (T) returned;
}
}
GsonResponseBodyConverterToString(Gson gson, Type type) {
this.gson = gson;
this.type = type;
}
@Override public T convert(ResponseBody value) throws IOException {
String returned = value.string();
try {
return gson.fromJson(returned, type);
}
catch (JsonParseException e) {
return (T) returned;
}
}
}
class GsonCustomConverterFactory extends Converter.Factory
{
public static GsonCustomConverterFactory create(Gson gson) {
return new GsonCustomConverterFactory(gson);
}
class GsonCustomConverterFactory extends Converter.Factory {
private final Gson gson;
private final GsonConverterFactory gsonConverterFactory;
private final Gson gson;
private final GsonConverterFactory gsonConverterFactory;
private GsonCustomConverterFactory(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
this.gson = gson;
this.gsonConverterFactory = GsonConverterFactory.create(gson);
}
public static GsonCustomConverterFactory create(Gson gson) {
return new GsonCustomConverterFactory(gson);
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
if(type.equals(String.class))
return new GsonResponseBodyConverterToString<Object>(gson, type);
else
return gsonConverterFactory.responseBodyConverter(type, annotations, retrofit);
}
private GsonCustomConverterFactory(Gson gson) {
if (gson == null)
throw new NullPointerException("gson == null");
this.gson = gson;
this.gsonConverterFactory = GsonConverterFactory.create(gson);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return gsonConverterFactory.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit);
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
if (type.equals(String.class))
return new GsonResponseBodyConverterToString<Object>(gson, type);
else
return gsonConverterFactory.responseBodyConverter(type, annotations, retrofit);
}
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return gsonConverterFactory.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit);
}
}
{{^java8}}
@@ -374,28 +393,29 @@ class GsonCustomConverterFactory extends Converter.Factory
*/
class DateTimeTypeAdapter extends TypeAdapter<DateTime> {
private final DateTimeFormatter formatter = ISODateTimeFormat.dateTime();
private final DateTimeFormatter parseFormatter = ISODateTimeFormat.dateOptionalTimeParser();
private final DateTimeFormatter printFormatter = ISODateTimeFormat.dateTime();
@Override
public void write(JsonWriter out, DateTime date) throws IOException {
if (date == null) {
out.nullValue();
} else {
out.value(formatter.print(date));
}
@Override
public void write(JsonWriter out, DateTime date) throws IOException {
if (date == null) {
out.nullValue();
} else {
out.value(printFormatter.print(date));
}
}
@Override
public DateTime read(JsonReader in) throws IOException {
switch (in.peek()) {
case NULL:
in.nextNull();
return null;
default:
String date = in.nextString();
return formatter.parseDateTime(date);
}
@Override
public DateTime read(JsonReader in) throws IOException {
switch (in.peek()) {
case NULL:
in.nextNull();
return null;
default:
String date = in.nextString();
return parseFormatter.parseDateTime(date);
}
}
}
/**
@@ -403,28 +423,28 @@ class DateTimeTypeAdapter extends TypeAdapter<DateTime> {
*/
class LocalDateTypeAdapter extends TypeAdapter<LocalDate> {
private final DateTimeFormatter formatter = ISODateTimeFormat.date();
private final DateTimeFormatter formatter = ISODateTimeFormat.date();
@Override
public void write(JsonWriter out, LocalDate date) throws IOException {
if (date == null) {
out.nullValue();
} else {
out.value(formatter.print(date));
}
@Override
public void write(JsonWriter out, LocalDate date) throws IOException {
if (date == null) {
out.nullValue();
} else {
out.value(formatter.print(date));
}
}
@Override
public LocalDate read(JsonReader in) throws IOException {
switch (in.peek()) {
case NULL:
in.nextNull();
return null;
default:
String date = in.nextString();
return formatter.parseLocalDate(date);
}
@Override
public LocalDate read(JsonReader in) throws IOException {
switch (in.peek()) {
case NULL:
in.nextNull();
return null;
default:
String date = in.nextString();
return formatter.parseLocalDate(date);
}
}
}
{{/java8}}
{{#java8}}
@@ -433,32 +453,31 @@ class LocalDateTypeAdapter extends TypeAdapter<LocalDate> {
*/
class OffsetDateTimeTypeAdapter extends TypeAdapter<OffsetDateTime> {
private final DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
private final DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
@Override
public void write(JsonWriter out, OffsetDateTime date) throws IOException {
if (date == null) {
out.nullValue();
} else {
out.value(formatter.format(date));
}
@Override
public void write(JsonWriter out, OffsetDateTime date) throws IOException {
if (date == null) {
out.nullValue();
} else {
out.value(formatter.format(date));
}
}
@Override
public OffsetDateTime read(JsonReader in) throws IOException {
switch (in.peek()) {
case NULL:
in.nextNull();
return null;
default:
String date = in.nextString();
if (date.endsWith("+0000")) {
date = date.substring(0, date.length()-5) + "Z";
}
return OffsetDateTime.parse(date, formatter);
@Override
public OffsetDateTime read(JsonReader in) throws IOException {
switch (in.peek()) {
case NULL:
in.nextNull();
return null;
default:
String date = in.nextString();
if (date.endsWith("+0000")) {
date = date.substring(0, date.length()-5) + "Z";
}
return OffsetDateTime.parse(date, formatter);
}
}
}
/**
@@ -466,27 +485,27 @@ class OffsetDateTimeTypeAdapter extends TypeAdapter<OffsetDateTime> {
*/
class LocalDateTypeAdapter extends TypeAdapter<LocalDate> {
private final DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE;
private final DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE;
@Override
public void write(JsonWriter out, LocalDate date) throws IOException {
if (date == null) {
out.nullValue();
} else {
out.value(formatter.format(date));
}
@Override
public void write(JsonWriter out, LocalDate date) throws IOException {
if (date == null) {
out.nullValue();
} else {
out.value(formatter.format(date));
}
}
@Override
public LocalDate read(JsonReader in) throws IOException {
switch (in.peek()) {
case NULL:
in.nextNull();
return null;
default:
String date = in.nextString();
return LocalDate.parse(date, formatter);
}
@Override
public LocalDate read(JsonReader in) throws IOException {
switch (in.peek()) {
case NULL:
in.nextNull();
return null;
default:
String date = in.nextString();
return LocalDate.parse(date, formatter);
}
}
}
{{/java8}}

View File

@@ -3,7 +3,8 @@ package {{package}};
import {{invokerPackage}}.CollectionFormats.*;
{{#useRxJava}}import rx.Observable;{{/useRxJava}}
{{^useRxJava}}import retrofit2.Call;{{/useRxJava}}
{{#useRxJava2}}import io.reactivex.Observable;{{/useRxJava2}}
{{#doNotUseRx}}import retrofit2.Call;{{/doNotUseRx}}
import retrofit2.http.*;
import okhttp3.RequestBody;
@@ -18,28 +19,38 @@ import java.util.List;
import java.util.Map;
{{/fullJavaUtil}}
{{#usePlay24WS}}
import play.libs.F;
import retrofit2.Response;
{{/usePlay24WS}}
{{#operations}}
public interface {{classname}} {
{{#operation}}
/**
* {{summary}}
* {{notes}}
{{#allParams}} * @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}} * @return Call&lt;{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}&gt;
{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}
{{/allParams}}
* @return Call&lt;{{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}Object{{/returnType}}&gt;
*/
{{#formParams}}{{#-first}}
{{#isMultipart}}@retrofit2.http.Multipart{{/isMultipart}}{{^isMultipart}}@retrofit2.http.FormUrlEncoded{{/isMultipart}}{{/-first}}{{/formParams}}
{{#formParams}}
{{#-first}}
{{#isMultipart}}@retrofit2.http.Multipart{{/isMultipart}}{{^isMultipart}}@retrofit2.http.FormUrlEncoded{{/isMultipart}}
{{/-first}}
{{/formParams}}
{{^formParams}}
{{#prioritizedContentTypes}}
{{#-first}}
@Headers({
"Content-Type:{{mediaType}}"
"Content-Type:{{mediaType}}"
})
{{/-first}}
{{/prioritizedContentTypes}}
{{/formParams}}
@{{httpMethod}}("{{path}}")
{{#useRxJava}}Observable{{/useRxJava}}{{^useRxJava}}Call{{/useRxJava}}<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}> {{operationId}}({{^allParams}});{{/allParams}}
@{{httpMethod}}("{{{path}}}")
{{^usePlay24WS}}{{^doNotUseRx}}Observable{{/doNotUseRx}}{{#doNotUseRx}}Call{{/doNotUseRx}}{{/usePlay24WS}}{{#usePlay24WS}}F.Promise<Response{{/usePlay24WS}}<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Object{{/returnType}}>{{#usePlay24WS}}>{{/usePlay24WS}} {{operationId}}({{^allParams}});{{/allParams}}
{{#allParams}}{{>libraries/retrofit2/queryParams}}{{>libraries/retrofit2/pathParams}}{{>libraries/retrofit2/headerParams}}{{>libraries/retrofit2/bodyParams}}{{>libraries/retrofit2/formParams}}{{#hasMore}}, {{/hasMore}}{{^hasMore}}
);{{/hasMore}}{{/allParams}}

View File

@@ -132,7 +132,7 @@ public class OAuth implements Interceptor {
if (accessTokenListener != null) {
accessTokenListener.notify((BasicOAuthToken) accessTokenResponse.getOAuthToken());
}
return getAccessToken().equals(requestAccessToken);
return !getAccessToken().equals(requestAccessToken);
} else {
return false;
}

View File

@@ -95,14 +95,24 @@ if(hasProperty('target') && target == 'android') {
ext {
oltu_version = "1.0.1"
retrofit_version = "2.0.2"
swagger_annotations_version = "1.5.8"
{{^usePlay24WS}}
retrofit_version = "2.2.0"
{{/usePlay24WS}}
{{#usePlay24WS}}
retrofit_version = "2.1.0"
jackson_version = "2.7.5"
play_version = "2.4.11"
{{/usePlay24WS}}
swagger_annotations_version = "1.5.12"
junit_version = "4.12"
{{#useRxJava}}
rx_java_version = "1.1.3"
rx_java_version = "1.2.9"
{{/useRxJava}}
{{#useRxJava2}}
rx_java_version = "2.0.7"
{{/useRxJava2}}
{{^java8}}
jodatime_version = "2.9.3"
jodatime_version = "2.9.4"
{{/java8}}
}
@@ -114,11 +124,22 @@ dependencies {
compile "com.squareup.retrofit2:adapter-rxjava:$retrofit_version"
compile "io.reactivex:rxjava:$rx_java_version"
{{/useRxJava}}
{{#useRxJava2}}
compile "com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0"
compile "io.reactivex.rxjava2:rxjava:$rx_java_version"
{{/useRxJava2}}
compile "io.swagger:swagger-annotations:$swagger_annotations_version"
compile "org.apache.oltu.oauth2:org.apache.oltu.oauth2.client:$oltu_version"
{{^java8}}
compile "joda-time:joda-time:$jodatime_version"
{{/java8}}
{{#usePlay24WS}}
compile "com.typesafe.play:play-java-ws_2.11:$play_version"
compile "com.squareup.retrofit2:converter-jackson:$retrofit_version"
compile "com.fasterxml.jackson.core:jackson-core:$jackson_version"
compile "com.fasterxml.jackson.core:jackson-annotations:$jackson_version"
compile "com.fasterxml.jackson.datatype:jackson-datatype-{{^java8}}joda{{/java8}}{{#java8}}jsr310{{/java8}}:$jackson_version"
{{/usePlay24WS}}
testCompile "junit:junit:$junit_version"
}

View File

@@ -9,19 +9,35 @@ lazy val root = (project in file(".")).
publishArtifact in (Compile, packageDoc) := false,
resolvers += Resolver.mavenLocal,
libraryDependencies ++= Seq(
"com.squareup.retrofit2" % "retrofit" % "2.0.2" % "compile",
"com.squareup.retrofit2" % "converter-scalars" % "2.0.2" % "compile",
"com.squareup.retrofit2" % "converter-gson" % "2.0.2" % "compile",
{{^usePlay24WS}}
"com.squareup.retrofit2" % "retrofit" % "2.2.0" % "compile",
"com.squareup.retrofit2" % "converter-scalars" % "2.2.0" % "compile",
"com.squareup.retrofit2" % "converter-gson" % "2.2.0" % "compile",
{{/usePlay24WS}}
{{#usePlay24WS}}
"com.typesafe.play" % "play-java-ws_2.11" % "2.4.11" % "compile",
"com.squareup.retrofit2" % "retrofit" % "2.1.0" % "compile",
"com.squareup.retrofit2" % "converter-scalars" % "2.1.0" % "compile",
"com.squareup.retrofit2" % "converter-gson" % "2.1.0" % "compile",
"com.squareup.retrofit2" % "converter-jackson" % "2.1.0" % "compile",
"com.fasterxml.jackson.core" % "jackson-core" % "2.7.5" % "compile",
"com.fasterxml.jackson.core" % "jackson-annotations" % "2.7.5" % "compile",
"com.fasterxml.jackson.core" % "jackson-databind" % "2.7.5" % "compile",
{{/usePlay24WS}}
{{#useRxJava}}
"com.squareup.retrofit2" % "adapter-rxjava" % "2.0.2" % "compile",
"io.reactivex" % "rxjava" % "1.1.3" % "compile",
"com.squareup.retrofit2" % "adapter-rxjava" % "{{^usePlay24WS}}2.2.0{{/usePlay24WS}}{{#usePlay24WS}}2.1.0{{/usePlay24WS}}" % "compile",
"io.reactivex" % "rxjava" % "1.2.9" % "compile",
{{/useRxJava}}
"io.swagger" % "swagger-annotations" % "1.5.8" % "compile",
{{#useRxJava2}}
"com.jakewharton.retrofit" % "retrofit2-rxjava2-adapter" % "1.0.0" % "compile",
"io.reactivex.rxjava2" % "rxjava" % "2.0.7" % "compile",
{{/useRxJava2}}
"io.swagger" % "swagger-annotations" % "1.5.12" % "compile",
"org.apache.oltu.oauth2" % "org.apache.oltu.oauth2.client" % "1.0.1" % "compile",
{{^java8}}
"joda-time" % "joda-time" % "2.9.3" % "compile",
"joda-time" % "joda-time" % "2.9.4" % "compile",
{{/java8}}
"junit" % "junit" % "4.12" % "test",
"com.novocode" % "junit-interface" % "0.10" % "test"
"com.novocode" % "junit-interface" % "0.11" % "test"
)
)

View File

@@ -0,0 +1,136 @@
package {{invokerPackage}};
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.*;
import retrofit2.Retrofit;
import retrofit2.converter.scalars.ScalarsConverterFactory;
import retrofit2.converter.jackson.JacksonConverterFactory;
import play.libs.Json;
import play.libs.ws.WSClient;
import {{invokerPackage}}.Play24CallAdapterFactory;
import {{invokerPackage}}.Play24CallFactory;
import okhttp3.Interceptor;
import {{invokerPackage}}.auth.ApiKeyAuth;
import {{invokerPackage}}.auth.Authentication;
/**
* API client
*/
public class ApiClient {
/** Underlying HTTP-client */
private WSClient wsClient;
/** Supported auths */
private Map<String, Authentication> authentications;
/** API base path */
private String basePath = "{{{basePath}}}";
public ApiClient(WSClient wsClient) {
this();
this.wsClient = wsClient;
}
public ApiClient() {
// Setup authentications (key: authentication name, value: authentication).
authentications = new HashMap<>();{{#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);
}
/**
* Creates a retrofit2 client for given API interface
*/
public <S> S createService(Class<S> serviceClass) {
if(!basePath.endsWith("/")) {
basePath = basePath + "/";
}
Map<String, String> extraHeaders = new HashMap<>();
List<Pair> extraQueryParams = new ArrayList<>();
for (String authName : authentications.keySet()) {
Authentication auth = authentications.get(authName);
if (auth == null) throw new RuntimeException("Authentication undefined: " + authName);
auth.applyToParams(extraQueryParams, extraHeaders);
}
return new Retrofit.Builder()
.baseUrl(basePath)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(JacksonConverterFactory.create(Json.mapper()))
.callFactory(new Play24CallFactory(wsClient, extraHeaders, extraQueryParams))
.addCallAdapterFactory(new Play24CallAdapterFactory())
.build()
.create(serviceClass);
}
/**
* Helper method to set API base path
*/
public ApiClient setBasePath(String basePath) {
this.basePath = basePath;
return this;
}
/**
* 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 API key value for the first API key authentication.
*/
public ApiClient setApiKey(String apiKey) {
for (Authentication auth : authentications.values()) {
if (auth instanceof ApiKeyAuth) {
((ApiKeyAuth) auth).setApiKey(apiKey);
return this;
}
}
throw new RuntimeException("No API key authentication configured!");
}
/**
* Helper method to set API key prefix for the first API key authentication.
*/
public ApiClient setApiKeyPrefix(String apiKeyPrefix) {
for (Authentication auth : authentications.values()) {
if (auth instanceof ApiKeyAuth) {
((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix);
return this;
}
}
throw new RuntimeException("No API key authentication configured!");
}
}

View File

@@ -0,0 +1,90 @@
package {{invokerPackage}};
import play.libs.F;
import retrofit2.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
/**
* Creates {@link CallAdapter} instances that convert {@link Call} into {@link play.libs.F.Promise}
*/
public class Play24CallAdapterFactory extends CallAdapter.Factory {
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (!(returnType instanceof ParameterizedType)) {
return null;
}
ParameterizedType type = (ParameterizedType) returnType;
if (type.getRawType() != F.Promise.class) {
return null;
}
return createAdapter((ParameterizedType) returnType);
}
private Type getTypeParam(ParameterizedType type) {
Type[] types = type.getActualTypeArguments();
if (types.length != 1) {
throw new IllegalStateException("Must be exactly one type parameter");
}
Type paramType = types[0];
if (paramType instanceof WildcardType) {
return ((WildcardType) paramType).getUpperBounds()[0];
}
return paramType;
}
private CallAdapter<?, F.Promise<?>> createAdapter(ParameterizedType returnType) {
Type parameterType = getTypeParam(returnType);
return new ValueAdapter(parameterType);
}
/**
* Adpater that coverts values returned by API interface into Play promises
*/
static final class ValueAdapter<R> implements CallAdapter<R, F.Promise<R>> {
private final Type responseType;
ValueAdapter(Type responseType) {
this.responseType = responseType;
}
@Override
public Type responseType() {
return responseType;
}
@Override
public F.Promise<R> adapt(final Call<R> call) {
final F.RedeemablePromise<R> promise = F.RedeemablePromise.empty();
call.enqueue(new Callback<R>() {
@Override
public void onResponse(Call<R> call, Response<R> response) {
if (response.isSuccessful()) {
promise.success(response.body());
} else {
promise.failure(new Exception(response.errorBody().toString()));
}
}
@Override
public void onFailure(Call<R> call, Throwable t) {
promise.failure(t);
}
});
return promise;
}
}
}

View File

@@ -0,0 +1,215 @@
package {{invokerPackage}};
import okhttp3.*;
import okio.Buffer;
import okio.BufferedSource;
import play.libs.F;
import play.libs.ws.WSClient;
import play.libs.ws.WSRequest;
import play.libs.ws.WSResponse;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Creates {@link Call} instances that invoke underlying {@link WSClient}
*/
public class Play24CallFactory implements okhttp3.Call.Factory {
/** PlayWS http client */
private final WSClient wsClient;
/** Extra headers to add to request */
private Map<String, String> extraHeaders = new HashMap<>();
/** Extra query parameters to add to request */
private List<Pair> extraQueryParams = new ArrayList<>();
public Play24CallFactory(WSClient wsClient) {
this.wsClient = wsClient;
}
public Play24CallFactory(WSClient wsClient, Map<String, String> extraHeaders,
List<Pair> extraQueryParams) {
this.wsClient = wsClient;
this.extraHeaders.putAll(extraHeaders);
this.extraQueryParams.addAll(extraQueryParams);
}
@Override
public Call newCall(Request request) {
// add extra headers
Request.Builder rb = request.newBuilder();
for (Map.Entry<String, String> header : this.extraHeaders.entrySet()) {
rb.addHeader(header.getKey(), header.getValue());
}
// add extra query params
if (!this.extraQueryParams.isEmpty()) {
String newQuery = request.url().uri().getQuery();
for (Pair queryParam : this.extraQueryParams) {
String param = String.format("%s=%s", queryParam.getName(), queryParam.getValue());
if (newQuery == null) {
newQuery = param;
} else {
newQuery += "&" + param;
}
}
URI newUri;
try {
newUri = new URI(request.url().uri().getScheme(), request.url().uri().getAuthority(),
request.url().uri().getPath(), newQuery, request.url().uri().getFragment());
rb.url(newUri.toURL());
} catch (MalformedURLException | URISyntaxException e) {
throw new RuntimeException("Error while updating an url", e);
}
}
return new PlayWSCall(wsClient, rb.build());
}
/**
* Call implementation that delegates to Play WS Client
*/
static class PlayWSCall implements Call {
private final WSClient wsClient;
private WSRequest wsRequest;
private final Request request;
public PlayWSCall(WSClient wsClient, Request request) {
this.wsClient = wsClient;
this.request = request;
}
@Override
public Request request() {
return request;
}
@Override
public void enqueue(final okhttp3.Callback responseCallback) {
final Call call = this;
final F.Promise<WSResponse> promise = executeAsync();
promise.onRedeem(new F.Callback<WSResponse>() {
@Override
public void invoke(WSResponse wsResponse) throws Throwable {
responseCallback.onResponse(call, PlayWSCall.this.toWSResponse(wsResponse));
}
});
promise.onFailure(new F.Callback<Throwable>() {
@Override
public void invoke(Throwable throwable) throws Throwable {
if (throwable instanceof IOException) {
responseCallback.onFailure(call, (IOException) throwable);
} else {
responseCallback.onFailure(call, new IOException(throwable));
}
}
});
}
F.Promise<WSResponse> executeAsync() {
try {
wsRequest = wsClient.url(request.url().uri().toString());
addHeaders(wsRequest);
if (request.body() != null) {
addBody(wsRequest);
}
return wsRequest.execute(request.method());
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
private void addHeaders(WSRequest wsRequest) {
for(Map.Entry<String, List<String>> entry : request.headers().toMultimap().entrySet()) {
List<String> values = entry.getValue();
for (String value : values) {
wsRequest.setHeader(entry.getKey(), value);
}
}
}
private void addBody(WSRequest wsRequest) throws IOException {
Buffer buffer = new Buffer();
request.body().writeTo(buffer);
wsRequest.setBody(buffer.inputStream());
wsRequest.setContentType(request.body().contentType().toString());
}
private Response toWSResponse(final WSResponse r) {
final Response.Builder builder = new Response.Builder();
builder.request(request)
.code(r.getStatus())
.body(new ResponseBody() {
@Override
public MediaType contentType() {
return MediaType.parse(r.getHeader("Content-Type"));
}
@Override
public long contentLength() {
return r.getBody().getBytes().length;
}
@Override
public BufferedSource source() {
return new Buffer().write(r.getBody().getBytes());
}
});
for (Map.Entry<String, List<String>> entry : r.getAllHeaders().entrySet()) {
for (String value : entry.getValue()) {
builder.addHeader(entry.getKey(), value);
}
}
builder.protocol(Protocol.HTTP_1_1);
return builder.build();
}
@Override
public Response execute() throws IOException {
throw new UnsupportedOperationException("Not supported");
}
@Override
public void cancel() {
throw new UnsupportedOperationException("Not supported");
}
@Override
public PlayWSCall clone() {
throw new UnsupportedOperationException("Not supported");
}
@Override
public boolean isExecuted() {
return false;
}
@Override
public boolean isCanceled() {
return false;
}
}
}

View File

@@ -0,0 +1,67 @@
{{>licenseInfo}}
package {{invokerPackage}}.auth;
import {{invokerPackage}}.Pair;
import java.util.Map;
import java.util.List;
/**
* Holds ApiKey auth info
*/
{{>generatedAnnotation}}
public class ApiKeyAuth implements Authentication {
private final String location;
private final String paramName;
private String apiKey;
private String apiKeyPrefix;
public ApiKeyAuth(String location, String paramName) {
this.location = location;
this.paramName = paramName;
}
public String getLocation() {
return location;
}
public String getParamName() {
return paramName;
}
public String getApiKey() {
return apiKey;
}
public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
public String getApiKeyPrefix() {
return apiKeyPrefix;
}
public void setApiKeyPrefix(String apiKeyPrefix) {
this.apiKeyPrefix = apiKeyPrefix;
}
@Override
public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams) {
if (apiKey == null) {
return;
}
String value;
if (apiKeyPrefix != null) {
value = apiKeyPrefix + " " + apiKey;
} else {
value = apiKey;
}
if ("query".equals(location)) {
queryParams.add(new Pair(paramName, value));
} else if ("header".equals(location)) {
headerParams.put(paramName, value);
}
}
}

View File

@@ -6,15 +6,34 @@
<packaging>jar</packaging>
<name>{{artifactId}}</name>
<version>{{artifactVersion}}</version>
<url>{{artifactUrl}}</url>
<description>{{artifactDescription}}</description>
<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>
<connection>{{scmConnection}}</connection>
<developerConnection>{{scmDeveloperConnection}}</developerConnection>
<url>{{scmUrl}}</url>
</scm>
<prerequisites>
<maven>2.2.0</maven>
</prerequisites>
<licenses>
<license>
<name>{{licenseName}}</name>
<url>{{licenseUrl}}</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>{{developerName}}</name>
<email>{{developerEmail}}</email>
<organization>{{developerOrganization}}</organization>
<organizationUrl>{{developerOrganizationUrl}}</organizationUrl>
</developer>
</developers>
<build>
<plugins>
<plugin>
@@ -100,9 +119,55 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>sign-artifacts</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>io.swagger</groupId>
@@ -148,6 +213,52 @@
<version>${retrofit-version}</version>
</dependency>
{{/useRxJava}}
{{#useRxJava2}}
<dependency>
<groupId>io.reactivex.rxjava2</groupId>
<artifactId>rxjava</artifactId>
<version>${rxjava-version}</version>
</dependency>
<dependency>
<groupId>com.jakewharton.retrofit</groupId>
<artifactId>retrofit2-rxjava2-adapter</artifactId>
<version>1.0.0</version>
</dependency>
{{/useRxJava2}}
{{#usePlay24WS}}
<!-- JSON processing: jackson -->
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>converter-jackson</artifactId>
<version>${retrofit-version}</version>
</dependency>
<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-{{^java8}}joda{{/java8}}{{#java8}}jsr310{{/java8}}</artifactId>
<version>${jackson-version}</version>
</dependency>
<dependency>
<groupId>com.typesafe.play</groupId>
<artifactId>play-java-ws_2.11</artifactId>
<version>${play-version}</version>
</dependency>
{{/usePlay24WS}}
<!-- test dependencies -->
<dependency>
@@ -162,11 +273,18 @@
<java.version>{{#java8}}1.8{{/java8}}{{^java8}}1.7{{/java8}}</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<swagger-core-version>1.5.9</swagger-core-version>
<retrofit-version>2.1.0</retrofit-version>
<swagger-core-version>1.5.12</swagger-core-version>
{{#usePlay24WS}}
<jackson-version>2.7.5</jackson-version>
<play-version>2.4.11</play-version>
{{/usePlay24WS}}
<retrofit-version>2.2.0</retrofit-version>
{{#useRxJava}}
<rxjava-version>1.1.6</rxjava-version>
<rxjava-version>1.2.9</rxjava-version>
{{/useRxJava}}
{{#useRxJava2}}
<rxjava-version>2.0.7</rxjava-version>
{{/useRxJava2}}
{{^java8}}
<jodatime-version>2.9.4</jodatime-version>
{{/java8}}

View File

@@ -4,6 +4,10 @@
@ApiModel(description = "{{{description}}}"){{/description}}
{{>generatedAnnotation}}{{#discriminator}}{{>typeInfoAnnotation}}{{/discriminator}}
public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#parcelableModel}}implements Parcelable {{#serializableModel}}, Serializable {{/serializableModel}}{{/parcelableModel}}{{^parcelableModel}}{{#serializableModel}}implements Serializable {{/serializableModel}}{{/parcelableModel}}{
{{#serializableModel}}
private static final long serialVersionUID = 1L;
{{/serializableModel}}
{{#vars}}
{{#isEnum}}
{{^isContainer}}
@@ -23,7 +27,12 @@ public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#parcela
{{#gson}}
@SerializedName("{{baseName}}")
{{/gson}}
{{#isContainer}}
private {{{datatypeWithEnum}}} {{name}}{{#required}} = {{{defaultValue}}}{{/required}}{{^required}} = null{{/required}};
{{/isContainer}}
{{^isContainer}}
private {{{datatypeWithEnum}}} {{name}} = {{{defaultValue}}};
{{/isContainer}}
{{/vars}}
{{#vars}}
@@ -92,7 +101,7 @@ public class {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{{#parcela
return {{#vars}}Objects.equals(this.{{name}}, {{classVarName}}.{{name}}){{#hasMore}} &&
{{/hasMore}}{{/vars}}{{#parent}} &&
super.equals(o){{/parent}};{{/hasVars}}{{^hasVars}}
return true;{{/hasVars}}
return {{#parent}}super.equals(o){{/parent}}{{^parent}}true{{/parent}};{{/hasVars}}
}
@Override

View File

@@ -6,11 +6,34 @@
<packaging>jar</packaging>
<name>{{artifactId}}</name>
<version>{{artifactVersion}}</version>
<url>{{artifactUrl}}</url>
<description>{{artifactDescription}}</description>
<scm>
<connection>{{scmConnection}}</connection>
<developerConnection>{{scmDeveloperConnection}}</developerConnection>
<url>{{scmUrl}}</url>
</scm>
<prerequisites>
<maven>2.2.0</maven>
</prerequisites>
<licenses>
<license>
<name>{{licenseName}}</name>
<url>{{licenseUrl}}</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<name>{{developerName}}</name>
<email>{{developerEmail}}</email>
<organization>{{developerOrganization}}</organization>
<organizationUrl>{{developerOrganizationUrl}}</organizationUrl>
</developer>
</developers>
<build>
<plugins>
<plugin>
@@ -95,7 +118,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<version>3.6.1</version>
<configuration>
{{#java8}}
<source>1.8</source>
@@ -111,9 +134,55 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.4</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>sign-artifacts</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>io.swagger</groupId>
@@ -194,7 +263,7 @@
<version>${commons_io_version}</version>
</dependency>
{{/supportJava6}}
{{#useBeanValidation}}
{{#useBeanValidation}}
<!-- Bean Validation API support -->
<dependency>
<groupId>javax.validation</groupId>
@@ -202,7 +271,7 @@
<version>1.1.0.Final</version>
<scope>provided</scope>
</dependency>
{{/useBeanValidation}}
{{/useBeanValidation}}
<!-- test dependencies -->
<dependency>
<groupId>junit</groupId>

View File

@@ -1,5 +1,7 @@
{{#jackson}}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "{{discriminator}}" )
@JsonSubTypes({
{{#children}}@JsonSubTypes.Type(value = {{name}}.class, name = "{{name}}"),{{/children}}
}){{/jackson}}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "{{discriminator}}", visible = true )
@JsonSubTypes({
{{#children}}
@JsonSubTypes.Type(value = {{name}}.class, name = "{{^vendorExtensions.x-discriminator-value}}{{name}}{{/vendorExtensions.x-discriminator-value}}{{#vendorExtensions.x-discriminator-value}}{{{vendorExtensions.x-discriminator-value}}}{{/vendorExtensions.x-discriminator-value}}"),
{{/children}}
}){{/jackson}}