forked from loafle/openapi-generator-original
Add full OAuth2 support to jersey2-experimental codegen (#6183)
* Add full Oauth2 support to Jersey client * Regenerate jersey2-experimental sample * Regenerate all java clients
This commit is contained in:
committed by
GitHub
parent
3de587826a
commit
779b176648
@@ -2,6 +2,9 @@
|
||||
|
||||
package {{invokerPackage}};
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -47,4 +50,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,9 @@ import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
|
||||
{{#hasOAuthMethods}}
|
||||
import com.github.scribejava.core.model.OAuth2AccessToken;
|
||||
{{/hasOAuthMethods}}
|
||||
import org.glassfish.jersey.client.ClientConfig;
|
||||
import org.glassfish.jersey.client.ClientProperties;
|
||||
import org.glassfish.jersey.client.HttpUrlConnectorProvider;
|
||||
@@ -43,7 +46,6 @@ import java.util.List;
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
|
||||
@@ -59,11 +61,10 @@ import {{invokerPackage}}.auth.HttpBasicAuth;
|
||||
import {{invokerPackage}}.auth.HttpBearerAuth;
|
||||
import {{invokerPackage}}.auth.HttpSignatureAuth;
|
||||
import {{invokerPackage}}.auth.ApiKeyAuth;
|
||||
import {{invokerPackage}}.model.AbstractOpenApiSchema;
|
||||
|
||||
{{#hasOAuthMethods}}
|
||||
import {{invokerPackage}}.auth.OAuth;
|
||||
{{/hasOAuthMethods}}
|
||||
import {{invokerPackage}}.model.AbstractOpenApiSchema;
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
public class ApiClient {
|
||||
@@ -178,7 +179,7 @@ public class ApiClient {
|
||||
authentications.put("{{name}}", new ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}"));
|
||||
{{/isApiKey}}
|
||||
{{#isOAuth}}
|
||||
authentications.put("{{name}}", new OAuth());
|
||||
authentications.put("{{name}}", new OAuth(basePath, "{{tokenUrl}}"));
|
||||
{{/isOAuth}}
|
||||
{{/authMethods}}
|
||||
// Prevent the authentications from being modified.
|
||||
@@ -191,6 +192,7 @@ public class ApiClient {
|
||||
|
||||
/**
|
||||
* Gets the JSON instance to do JSON serialization and deserialization.
|
||||
*
|
||||
* @return JSON
|
||||
*/
|
||||
public JSON getJSON() {
|
||||
@@ -212,6 +214,7 @@ public class ApiClient {
|
||||
|
||||
public ApiClient setBasePath(String basePath) {
|
||||
this.basePath = basePath;
|
||||
setOauthBasePath(basePath);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -221,6 +224,7 @@ public class ApiClient {
|
||||
|
||||
public ApiClient setServers(List<ServerConfiguration> servers) {
|
||||
this.servers = servers;
|
||||
updateBasePath();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -230,6 +234,7 @@ public class ApiClient {
|
||||
|
||||
public ApiClient setServerIndex(Integer serverIndex) {
|
||||
this.serverIndex = serverIndex;
|
||||
updateBasePath();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -239,11 +244,25 @@ public class ApiClient {
|
||||
|
||||
public ApiClient setServerVariables(Map<String, String> serverVariables) {
|
||||
this.serverVariables = serverVariables;
|
||||
updateBasePath();
|
||||
return this;
|
||||
}
|
||||
|
||||
private void updateBasePath() {
|
||||
setBasePath(servers.get(serverIndex).URL(serverVariables));
|
||||
}
|
||||
|
||||
private void setOauthBasePath(String basePath) {
|
||||
for(Authentication auth : authentications.values()) {
|
||||
if (auth instanceof OAuth) {
|
||||
((OAuth) auth).setBasePath(basePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get authentications (key: authentication name, value: authentication).
|
||||
*
|
||||
* @return Map of authentication object
|
||||
*/
|
||||
public Map<String, Authentication> getAuthentications() {
|
||||
@@ -262,13 +281,14 @@ public class ApiClient {
|
||||
|
||||
/**
|
||||
* Helper method to set username for the first HTTP basic authentication.
|
||||
*
|
||||
* @param username Username
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
public ApiClient setUsername(String username) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof HttpBasicAuth) {
|
||||
((HttpBasicAuth) auth).setUsername(username);
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No HTTP basic authentication configured!");
|
||||
@@ -276,13 +296,14 @@ public class ApiClient {
|
||||
|
||||
/**
|
||||
* Helper method to set password for the first HTTP basic authentication.
|
||||
*
|
||||
* @param password Password
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
public ApiClient setPassword(String password) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof HttpBasicAuth) {
|
||||
((HttpBasicAuth) auth).setPassword(password);
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No HTTP basic authentication configured!");
|
||||
@@ -290,13 +311,14 @@ 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) {
|
||||
public ApiClient setApiKey(String apiKey) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof ApiKeyAuth) {
|
||||
((ApiKeyAuth) auth).setApiKey(apiKey);
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No API key authentication configured!");
|
||||
@@ -307,29 +329,31 @@ public class ApiClient {
|
||||
*
|
||||
* @param secrets Hash map from authentication name to its secret.
|
||||
*/
|
||||
public void configureApiKeys(HashMap<String, String> secrets) {
|
||||
public ApiClient configureApiKeys(HashMap<String, String> secrets) {
|
||||
for (Map.Entry<String, Authentication> authEntry : authentications.entrySet()) {
|
||||
Authentication auth = authEntry.getValue();
|
||||
if (auth instanceof ApiKeyAuth) {
|
||||
String name = authEntry.getKey();
|
||||
// respect x-auth-id-alias property
|
||||
name = authenticationLookup.getOrDefault(name, name);
|
||||
name = authenticationLookup.containsKey(name) ? authenticationLookup.get(name) : name;
|
||||
if (secrets.containsKey(name)) {
|
||||
((ApiKeyAuth) auth).setApiKey(secrets.get(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to set API key prefix for the first API key authentication.
|
||||
*
|
||||
* @param apiKeyPrefix API key prefix
|
||||
*/
|
||||
public void setApiKeyPrefix(String apiKeyPrefix) {
|
||||
public ApiClient setApiKeyPrefix(String apiKeyPrefix) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof ApiKeyAuth) {
|
||||
((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix);
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No API key authentication configured!");
|
||||
@@ -337,28 +361,92 @@ public class ApiClient {
|
||||
|
||||
/**
|
||||
* Helper method to set bearer token for the first Bearer authentication.
|
||||
*
|
||||
* @param bearerToken Bearer token
|
||||
*/
|
||||
public void setBearerToken(String bearerToken) {
|
||||
public ApiClient setBearerToken(String bearerToken) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof HttpBearerAuth) {
|
||||
((HttpBearerAuth) auth).setBearerToken(bearerToken);
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No Bearer authentication configured!");
|
||||
}
|
||||
|
||||
|
||||
{{#hasOAuthMethods}}
|
||||
/**
|
||||
* Helper method to set access token for the first OAuth2 authentication.
|
||||
* @param accessToken Access token
|
||||
*/
|
||||
public void setAccessToken(String accessToken) {
|
||||
public ApiClient setAccessToken(String accessToken) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof OAuth) {
|
||||
((OAuth) auth).setAccessToken(accessToken);
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No OAuth2 authentication configured!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to set the credentials for the first OAuth2 authentication.
|
||||
*
|
||||
* @param clientId the client ID
|
||||
* @param clientSecret the client secret
|
||||
*/
|
||||
public ApiClient setOauthCredentials(String clientId, String clientSecret) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof OAuth) {
|
||||
((OAuth) auth).setCredentials(clientId, clientSecret);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No OAuth2 authentication configured!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to set the password flow for the first OAuth2 authentication.
|
||||
*
|
||||
* @param username the user name
|
||||
* @param password the user password
|
||||
*/
|
||||
public ApiClient setOauthPasswordFlow(String username, String password) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof OAuth) {
|
||||
((OAuth) auth).usePasswordFlow(username, password);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No OAuth2 authentication configured!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to set the authorization code flow for the first OAuth2 authentication.
|
||||
*
|
||||
* @param code the authorization code
|
||||
*/
|
||||
public ApiClient setOauthAuthorizationCodeFlow(String code) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof OAuth) {
|
||||
((OAuth) auth).useAuthorizationCodeFlow(code);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No OAuth2 authentication configured!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to set the scopes for the first OAuth2 authentication.
|
||||
*
|
||||
* @param scope the oauth scope
|
||||
*/
|
||||
public ApiClient setOauthScope(String scope) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof OAuth) {
|
||||
((OAuth) auth).setScope(scope);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No OAuth2 authentication configured!");
|
||||
@@ -787,9 +875,9 @@ public class ApiClient {
|
||||
}
|
||||
|
||||
if (matchCounter > 1 && "oneOf".equals(schema.getSchemaType())) {// more than 1 match for oneOf
|
||||
throw new ApiException("Response body is invalid as it matches more than one schema (" + String.join(", ", matchSchemas) + ") defined in the oneOf model: " + schema.getClass().getName());
|
||||
throw new ApiException("Response body is invalid as it matches more than one schema (" + StringUtil.join(matchSchemas, ", ") + ") defined in the oneOf model: " + schema.getClass().getName());
|
||||
} else if (matchCounter == 0) { // fail to match any in oneOf/anyOf schemas
|
||||
throw new ApiException("Response body is invalid as it doens't match any schemas (" + String.join(", ", schema.getSchemas().keySet()) + ") defined in the oneOf/anyOf model: " + schema.getClass().getName());
|
||||
throw new ApiException("Response body is invalid as it doens't match any schemas (" + StringUtil.join(schema.getSchemas().keySet(), ", ") + ") defined in the oneOf/anyOf model: " + schema.getClass().getName());
|
||||
} else { // only one matched
|
||||
schema.setActualInstance(result);
|
||||
return schema;
|
||||
@@ -910,29 +998,35 @@ public class ApiClient {
|
||||
* @return The response body in type of string
|
||||
* @throws ApiException API exception
|
||||
*/
|
||||
public <T> ApiResponse<T> invokeAPI(String operation, String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, String> cookieParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames, GenericType<T> returnType, AbstractOpenApiSchema schema) throws ApiException {
|
||||
public <T> ApiResponse<T> invokeAPI(
|
||||
String operation,
|
||||
String path,
|
||||
String method,
|
||||
List<Pair> queryParams,
|
||||
Object body,
|
||||
Map<String, String> headerParams,
|
||||
Map<String, String> cookieParams,
|
||||
Map<String, Object> formParams,
|
||||
String accept,
|
||||
String contentType,
|
||||
String[] authNames,
|
||||
GenericType<T> returnType,
|
||||
AbstractOpenApiSchema schema)
|
||||
throws ApiException {
|
||||
|
||||
// Not using `.target(targetURL).path(path)` below,
|
||||
// to support (constant) query string in `path`, e.g. "/posts?draft=1"
|
||||
String targetURL;
|
||||
if (serverIndex != null) {
|
||||
Integer index;
|
||||
List<ServerConfiguration> serverConfigurations;
|
||||
Map<String, String> variables;
|
||||
|
||||
if (operationServers.containsKey(operation)) {
|
||||
index = operationServerIndex.getOrDefault(operation, serverIndex);
|
||||
variables = operationServerVariables.getOrDefault(operation, serverVariables);
|
||||
serverConfigurations = operationServers.get(operation);
|
||||
} else {
|
||||
index = serverIndex;
|
||||
variables = serverVariables;
|
||||
serverConfigurations = servers;
|
||||
}
|
||||
if (operationServers.containsKey(operation)) {
|
||||
Integer index = operationServerIndex.containsKey(operation) ? operationServerIndex.get(operation) : serverIndex;
|
||||
Map<String, String> variables = operationServerVariables.containsKey(operation) ?
|
||||
operationServerVariables.get(operation) : serverVariables;
|
||||
List<ServerConfiguration> serverConfigurations = operationServers.get(operation);
|
||||
if (index < 0 || index >= serverConfigurations.size()) {
|
||||
throw new ArrayIndexOutOfBoundsException(String.format(
|
||||
"Invalid index %d when selecting the host settings. Must be less than %d", index, serverConfigurations.size()
|
||||
));
|
||||
throw new ArrayIndexOutOfBoundsException(
|
||||
String.format(
|
||||
"Invalid index %d when selecting the host settings. Must be less than %d",
|
||||
index, serverConfigurations.size()));
|
||||
}
|
||||
targetURL = serverConfigurations.get(index).URL(variables) + path;
|
||||
} else {
|
||||
@@ -950,13 +1044,6 @@ public class ApiClient {
|
||||
|
||||
Invocation.Builder invocationBuilder = target.request().accept(accept);
|
||||
|
||||
for (Entry<String, String> entry : headerParams.entrySet()) {
|
||||
String value = entry.getValue();
|
||||
if (value != null) {
|
||||
invocationBuilder = invocationBuilder.header(entry.getKey(), value);
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry<String, String> entry : cookieParams.entrySet()) {
|
||||
String value = entry.getValue();
|
||||
if (value != null) {
|
||||
@@ -971,63 +1058,63 @@ public class ApiClient {
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry<String, String> entry : defaultHeaderMap.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (!headerParams.containsKey(key)) {
|
||||
String value = entry.getValue();
|
||||
if (value != null) {
|
||||
invocationBuilder = invocationBuilder.header(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Entity<?> entity = serialize(body, formParams, contentType);
|
||||
|
||||
// put all headers in one place
|
||||
Map<String, String> allHeaderParams = new HashMap<>();
|
||||
allHeaderParams.putAll(defaultHeaderMap);
|
||||
Map<String, String> allHeaderParams = new HashMap<>(defaultHeaderMap);
|
||||
allHeaderParams.putAll(headerParams);
|
||||
|
||||
|
||||
// update different parameters (e.g. headers) for authentication
|
||||
updateParamsForAuth(authNames, queryParams, allHeaderParams, cookieParams, serializeToString(body, formParams, contentType), method, target.getUri());
|
||||
updateParamsForAuth(
|
||||
authNames,
|
||||
queryParams,
|
||||
allHeaderParams,
|
||||
cookieParams,
|
||||
serializeToString(body, formParams, contentType),
|
||||
method,
|
||||
target.getUri());
|
||||
|
||||
for (Entry<String, String> entry : allHeaderParams.entrySet()) {
|
||||
String value = entry.getValue();
|
||||
if (value != null) {
|
||||
invocationBuilder = invocationBuilder.header(entry.getKey(), value);
|
||||
}
|
||||
}
|
||||
|
||||
Response response = null;
|
||||
|
||||
try {
|
||||
if ("GET".equals(method)) {
|
||||
response = invocationBuilder.get();
|
||||
} else if ("POST".equals(method)) {
|
||||
response = invocationBuilder.post(entity);
|
||||
} else if ("PUT".equals(method)) {
|
||||
response = invocationBuilder.put(entity);
|
||||
} else if ("DELETE".equals(method)) {
|
||||
response = invocationBuilder.method("DELETE", entity);
|
||||
} else if ("PATCH".equals(method)) {
|
||||
response = invocationBuilder.method("PATCH", entity);
|
||||
} else if ("HEAD".equals(method)) {
|
||||
response = invocationBuilder.head();
|
||||
} else if ("OPTIONS".equals(method)) {
|
||||
response = invocationBuilder.options();
|
||||
} else if ("TRACE".equals(method)) {
|
||||
response = invocationBuilder.trace();
|
||||
} else {
|
||||
throw new ApiException(500, "unknown method type " + method);
|
||||
response = sendRequest(method, invocationBuilder, entity);
|
||||
|
||||
// If OAuth is used and a status 401 is received, renew the access token and retry the request
|
||||
if (response.getStatusInfo() == Status.UNAUTHORIZED) {
|
||||
for (String authName : authNames) {
|
||||
Authentication authentication = authentications.get(authName);
|
||||
if (authentication instanceof OAuth) {
|
||||
OAuth2AccessToken accessToken = ((OAuth) authentication).renewAccessToken();
|
||||
if (accessToken != null) {
|
||||
invocationBuilder.header("Authorization", null);
|
||||
invocationBuilder.header("Authorization", "Bearer " + accessToken.getAccessToken());
|
||||
response = sendRequest(method, invocationBuilder, entity);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int statusCode = response.getStatusInfo().getStatusCode();
|
||||
Map<String, List<String>> responseHeaders = buildResponseHeaders(response);
|
||||
|
||||
if (response.getStatus() == Status.NO_CONTENT.getStatusCode()) {
|
||||
return new ApiResponse<{{#supportJava6}}T{{/supportJava6}}>(statusCode, responseHeaders);
|
||||
if (response.getStatusInfo() == Status.NO_CONTENT) {
|
||||
return new ApiResponse<T>(statusCode, responseHeaders);
|
||||
} else if (response.getStatusInfo().getFamily() == Status.Family.SUCCESSFUL) {
|
||||
if (returnType == null)
|
||||
return new ApiResponse<{{#supportJava6}}T{{/supportJava6}}>(statusCode, responseHeaders);
|
||||
else
|
||||
if (schema == null) {
|
||||
return new ApiResponse<>(statusCode, responseHeaders, deserialize(response, returnType));
|
||||
} else { // oneOf/anyOf
|
||||
return new ApiResponse<>(statusCode, responseHeaders, (T)deserializeSchemas(response, schema));
|
||||
}
|
||||
if (returnType == null) return new ApiResponse<T>(statusCode, responseHeaders);
|
||||
else if (schema == null) {
|
||||
return new ApiResponse<T>(statusCode, responseHeaders, deserialize(response, returnType));
|
||||
} else { // oneOf/anyOf
|
||||
return new ApiResponse<T>(
|
||||
statusCode, responseHeaders, (T) deserializeSchemas(response, schema));
|
||||
}
|
||||
} else {
|
||||
String message = "error";
|
||||
String respBody = null;
|
||||
@@ -1040,20 +1127,34 @@ public class ApiClient {
|
||||
}
|
||||
}
|
||||
throw new ApiException(
|
||||
response.getStatus(),
|
||||
message,
|
||||
buildResponseHeaders(response),
|
||||
respBody);
|
||||
response.getStatus(), message, buildResponseHeaders(response), respBody);
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
response.close();
|
||||
} catch (Exception e) {
|
||||
// it's not critical, since the response object is local in method invokeAPI; that's fine, just continue
|
||||
// it's not critical, since the response object is local in method invokeAPI; that's fine,
|
||||
// just continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Response sendRequest(String method, Invocation.Builder invocationBuilder, Entity<?> entity) {
|
||||
Response response;
|
||||
if ("POST".equals(method)) {
|
||||
response = invocationBuilder.post(entity);
|
||||
} else if ("PUT".equals(method)) {
|
||||
response = invocationBuilder.put(entity);
|
||||
} else if ("DELETE".equals(method)) {
|
||||
response = invocationBuilder.method("DELETE", entity);
|
||||
} else if ("PATCH".equals(method)) {
|
||||
response = invocationBuilder.method("PATCH", entity);
|
||||
} else {
|
||||
response = invocationBuilder.method(method);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Add qualified name of the operation as a first parameter.
|
||||
*/
|
||||
|
||||
@@ -4,27 +4,169 @@ package {{invokerPackage}}.auth;
|
||||
|
||||
import {{invokerPackage}}.Pair;
|
||||
import {{invokerPackage}}.ApiException;
|
||||
import com.github.scribejava.core.builder.ServiceBuilder;
|
||||
import com.github.scribejava.core.builder.api.DefaultApi20;
|
||||
import com.github.scribejava.core.exceptions.OAuthException;
|
||||
import com.github.scribejava.core.model.OAuth2AccessToken;
|
||||
import com.github.scribejava.core.oauth.OAuth20Service;
|
||||
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
{{>generatedAnnotation}}
|
||||
public class OAuth implements Authentication {
|
||||
private String accessToken;
|
||||
private static final Logger log = Logger.getLogger(OAuth.class.getName());
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
private String tokenUrl;
|
||||
private String absoluteTokenUrl;
|
||||
private OAuthFlow flow = OAuthFlow.application;
|
||||
private OAuth20Service service;
|
||||
private DefaultApi20 authApi;
|
||||
private String scope;
|
||||
private String username;
|
||||
private String password;
|
||||
private String code;
|
||||
private volatile OAuth2AccessToken accessToken;
|
||||
|
||||
public OAuth(String basePath, String tokenUrl) {
|
||||
this.tokenUrl = tokenUrl;
|
||||
this.absoluteTokenUrl = createAbsoluteTokenUrl(basePath, tokenUrl);
|
||||
authApi = new DefaultApi20() {
|
||||
@Override
|
||||
public String getAccessTokenEndpoint() {
|
||||
return absoluteTokenUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getAuthorizationBaseUrl() {
|
||||
throw new UnsupportedOperationException("Shouldn't get there !");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
private static String createAbsoluteTokenUrl(String basePath, String tokenUrl) {
|
||||
if (!URI.create(tokenUrl).isAbsolute()) {
|
||||
try {
|
||||
return UriBuilder.fromPath(basePath).path(tokenUrl).build().toURL().toString();
|
||||
} catch (MalformedURLException e) {
|
||||
log.log(Level.SEVERE, "Couldn't create absolute token URL", e);
|
||||
}
|
||||
}
|
||||
return tokenUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams, Map<String, String> cookieParams, String payload, String method, URI uri) throws ApiException {
|
||||
public void applyToParams(
|
||||
List<Pair> queryParams,
|
||||
Map<String, String> headerParams,
|
||||
Map<String, String> cookieParams,
|
||||
String payload,
|
||||
String method,
|
||||
URI uri)
|
||||
throws ApiException {
|
||||
|
||||
if (accessToken == null) {
|
||||
obtainAccessToken(null);
|
||||
}
|
||||
if (accessToken != null) {
|
||||
headerParams.put("Authorization", "Bearer " + accessToken);
|
||||
headerParams.put("Authorization", "Bearer " + accessToken.getAccessToken());
|
||||
}
|
||||
}
|
||||
|
||||
public OAuth2AccessToken renewAccessToken() throws ApiException {
|
||||
String refreshToken = null;
|
||||
if (accessToken != null) {
|
||||
refreshToken = accessToken.getRefreshToken();
|
||||
accessToken = null;
|
||||
}
|
||||
return obtainAccessToken(refreshToken);
|
||||
}
|
||||
|
||||
public synchronized OAuth2AccessToken obtainAccessToken(String refreshToken) throws ApiException {
|
||||
if (service == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
if (refreshToken != null) {
|
||||
return service.refreshAccessToken(refreshToken);
|
||||
}
|
||||
} catch (OAuthException | InterruptedException | ExecutionException | IOException e) {
|
||||
log.log(Level.FINE, "Refreshing the access token using the refresh token failed", e);
|
||||
}
|
||||
try {
|
||||
switch (flow) {
|
||||
case password:
|
||||
if (username != null && password != null) {
|
||||
accessToken = service.getAccessTokenPasswordGrant(username, password, scope);
|
||||
}
|
||||
break;
|
||||
case accessCode:
|
||||
if (code != null) {
|
||||
accessToken = service.getAccessToken(code);
|
||||
code = null;
|
||||
}
|
||||
break;
|
||||
case application:
|
||||
accessToken = service.getAccessTokenClientCredentialsGrant(scope);
|
||||
}
|
||||
} catch (OAuthException | InterruptedException | ExecutionException | IOException e) {
|
||||
throw new ApiException(e);
|
||||
}
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public OAuth2AccessToken getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public OAuth setAccessToken(OAuth2AccessToken accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuth setAccessToken(String accessToken) {
|
||||
this.accessToken = new OAuth2AccessToken(accessToken);
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuth setScope(String scope) {
|
||||
this.scope = scope;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuth setCredentials(String clientId, String clientSecret) {
|
||||
service = new ServiceBuilder(clientId)
|
||||
.apiSecret(clientSecret)
|
||||
.build(authApi);
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuth usePasswordFlow(String username, String password) {
|
||||
this.flow = OAuthFlow.password;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuth useAuthorizationCodeFlow(String code) {
|
||||
this.flow = OAuthFlow.accessCode;
|
||||
this.code = code;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuth setFlow(OAuthFlow flow) {
|
||||
this.flow = flow;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setBasePath(String basePath) {
|
||||
this.absoluteTokenUrl = createAbsoluteTokenUrl(basePath, tokenUrl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,6 +343,13 @@
|
||||
<artifactId>tomitribe-http-signatures</artifactId>
|
||||
<version>${http-signature-version}</version>
|
||||
</dependency>
|
||||
{{#hasOAuthMethods}}
|
||||
<dependency>
|
||||
<groupId>com.github.scribejava</groupId>
|
||||
<artifactId>scribejava-apis</artifactId>
|
||||
<version>6.9.0</version>
|
||||
</dependency>
|
||||
{{/hasOAuthMethods}}
|
||||
{{#useBeanValidation}}
|
||||
<!-- Bean Validation API support -->
|
||||
<dependency>
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.openapitools.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -58,4 +61,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.openapitools.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -58,4 +61,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.openapitools.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -58,4 +61,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.openapitools.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -58,4 +61,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,6 +284,11 @@
|
||||
<artifactId>tomitribe-http-signatures</artifactId>
|
||||
<version>${http-signature-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.scribejava</groupId>
|
||||
<artifactId>scribejava-apis</artifactId>
|
||||
<version>6.9.0</version>
|
||||
</dependency>
|
||||
<!-- test dependencies -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
|
||||
@@ -11,6 +11,7 @@ import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
|
||||
import com.github.scribejava.core.model.OAuth2AccessToken;
|
||||
import org.glassfish.jersey.client.ClientConfig;
|
||||
import org.glassfish.jersey.client.ClientProperties;
|
||||
import org.glassfish.jersey.client.HttpUrlConnectorProvider;
|
||||
@@ -37,7 +38,6 @@ import java.util.List;
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
|
||||
@@ -53,9 +53,8 @@ import org.openapitools.client.auth.HttpBasicAuth;
|
||||
import org.openapitools.client.auth.HttpBearerAuth;
|
||||
import org.openapitools.client.auth.HttpSignatureAuth;
|
||||
import org.openapitools.client.auth.ApiKeyAuth;
|
||||
import org.openapitools.client.model.AbstractOpenApiSchema;
|
||||
|
||||
import org.openapitools.client.auth.OAuth;
|
||||
import org.openapitools.client.model.AbstractOpenApiSchema;
|
||||
|
||||
|
||||
public class ApiClient {
|
||||
@@ -168,7 +167,7 @@ public class ApiClient {
|
||||
authentications.put("bearer_test", new HttpBearerAuth("bearer"));
|
||||
authentications.put("http_basic_test", new HttpBasicAuth());
|
||||
authentications.put("http_signature_test", new HttpSignatureAuth("http_signature_test", null, null));
|
||||
authentications.put("petstore_auth", new OAuth());
|
||||
authentications.put("petstore_auth", new OAuth(basePath, ""));
|
||||
// Prevent the authentications from being modified.
|
||||
authentications = Collections.unmodifiableMap(authentications);
|
||||
|
||||
@@ -178,6 +177,7 @@ public class ApiClient {
|
||||
|
||||
/**
|
||||
* Gets the JSON instance to do JSON serialization and deserialization.
|
||||
*
|
||||
* @return JSON
|
||||
*/
|
||||
public JSON getJSON() {
|
||||
@@ -199,6 +199,7 @@ public class ApiClient {
|
||||
|
||||
public ApiClient setBasePath(String basePath) {
|
||||
this.basePath = basePath;
|
||||
setOauthBasePath(basePath);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -208,6 +209,7 @@ public class ApiClient {
|
||||
|
||||
public ApiClient setServers(List<ServerConfiguration> servers) {
|
||||
this.servers = servers;
|
||||
updateBasePath();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -217,6 +219,7 @@ public class ApiClient {
|
||||
|
||||
public ApiClient setServerIndex(Integer serverIndex) {
|
||||
this.serverIndex = serverIndex;
|
||||
updateBasePath();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -226,11 +229,25 @@ public class ApiClient {
|
||||
|
||||
public ApiClient setServerVariables(Map<String, String> serverVariables) {
|
||||
this.serverVariables = serverVariables;
|
||||
updateBasePath();
|
||||
return this;
|
||||
}
|
||||
|
||||
private void updateBasePath() {
|
||||
setBasePath(servers.get(serverIndex).URL(serverVariables));
|
||||
}
|
||||
|
||||
private void setOauthBasePath(String basePath) {
|
||||
for(Authentication auth : authentications.values()) {
|
||||
if (auth instanceof OAuth) {
|
||||
((OAuth) auth).setBasePath(basePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get authentications (key: authentication name, value: authentication).
|
||||
*
|
||||
* @return Map of authentication object
|
||||
*/
|
||||
public Map<String, Authentication> getAuthentications() {
|
||||
@@ -249,13 +266,14 @@ public class ApiClient {
|
||||
|
||||
/**
|
||||
* Helper method to set username for the first HTTP basic authentication.
|
||||
*
|
||||
* @param username Username
|
||||
*/
|
||||
public void setUsername(String username) {
|
||||
public ApiClient setUsername(String username) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof HttpBasicAuth) {
|
||||
((HttpBasicAuth) auth).setUsername(username);
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No HTTP basic authentication configured!");
|
||||
@@ -263,13 +281,14 @@ public class ApiClient {
|
||||
|
||||
/**
|
||||
* Helper method to set password for the first HTTP basic authentication.
|
||||
*
|
||||
* @param password Password
|
||||
*/
|
||||
public void setPassword(String password) {
|
||||
public ApiClient setPassword(String password) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof HttpBasicAuth) {
|
||||
((HttpBasicAuth) auth).setPassword(password);
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No HTTP basic authentication configured!");
|
||||
@@ -277,13 +296,14 @@ 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) {
|
||||
public ApiClient setApiKey(String apiKey) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof ApiKeyAuth) {
|
||||
((ApiKeyAuth) auth).setApiKey(apiKey);
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No API key authentication configured!");
|
||||
@@ -294,29 +314,31 @@ public class ApiClient {
|
||||
*
|
||||
* @param secrets Hash map from authentication name to its secret.
|
||||
*/
|
||||
public void configureApiKeys(HashMap<String, String> secrets) {
|
||||
public ApiClient configureApiKeys(HashMap<String, String> secrets) {
|
||||
for (Map.Entry<String, Authentication> authEntry : authentications.entrySet()) {
|
||||
Authentication auth = authEntry.getValue();
|
||||
if (auth instanceof ApiKeyAuth) {
|
||||
String name = authEntry.getKey();
|
||||
// respect x-auth-id-alias property
|
||||
name = authenticationLookup.getOrDefault(name, name);
|
||||
name = authenticationLookup.containsKey(name) ? authenticationLookup.get(name) : name;
|
||||
if (secrets.containsKey(name)) {
|
||||
((ApiKeyAuth) auth).setApiKey(secrets.get(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to set API key prefix for the first API key authentication.
|
||||
*
|
||||
* @param apiKeyPrefix API key prefix
|
||||
*/
|
||||
public void setApiKeyPrefix(String apiKeyPrefix) {
|
||||
public ApiClient setApiKeyPrefix(String apiKeyPrefix) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof ApiKeyAuth) {
|
||||
((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix);
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No API key authentication configured!");
|
||||
@@ -324,27 +346,91 @@ public class ApiClient {
|
||||
|
||||
/**
|
||||
* Helper method to set bearer token for the first Bearer authentication.
|
||||
*
|
||||
* @param bearerToken Bearer token
|
||||
*/
|
||||
public void setBearerToken(String bearerToken) {
|
||||
public ApiClient setBearerToken(String bearerToken) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof HttpBearerAuth) {
|
||||
((HttpBearerAuth) auth).setBearerToken(bearerToken);
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No Bearer authentication configured!");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper method to set access token for the first OAuth2 authentication.
|
||||
* @param accessToken Access token
|
||||
*/
|
||||
public void setAccessToken(String accessToken) {
|
||||
public ApiClient setAccessToken(String accessToken) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof OAuth) {
|
||||
((OAuth) auth).setAccessToken(accessToken);
|
||||
return;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No OAuth2 authentication configured!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to set the credentials for the first OAuth2 authentication.
|
||||
*
|
||||
* @param clientId the client ID
|
||||
* @param clientSecret the client secret
|
||||
*/
|
||||
public ApiClient setOauthCredentials(String clientId, String clientSecret) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof OAuth) {
|
||||
((OAuth) auth).setCredentials(clientId, clientSecret);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No OAuth2 authentication configured!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to set the password flow for the first OAuth2 authentication.
|
||||
*
|
||||
* @param username the user name
|
||||
* @param password the user password
|
||||
*/
|
||||
public ApiClient setOauthPasswordFlow(String username, String password) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof OAuth) {
|
||||
((OAuth) auth).usePasswordFlow(username, password);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No OAuth2 authentication configured!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to set the authorization code flow for the first OAuth2 authentication.
|
||||
*
|
||||
* @param code the authorization code
|
||||
*/
|
||||
public ApiClient setOauthAuthorizationCodeFlow(String code) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof OAuth) {
|
||||
((OAuth) auth).useAuthorizationCodeFlow(code);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No OAuth2 authentication configured!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to set the scopes for the first OAuth2 authentication.
|
||||
*
|
||||
* @param scope the oauth scope
|
||||
*/
|
||||
public ApiClient setOauthScope(String scope) {
|
||||
for (Authentication auth : authentications.values()) {
|
||||
if (auth instanceof OAuth) {
|
||||
((OAuth) auth).setScope(scope);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("No OAuth2 authentication configured!");
|
||||
@@ -772,9 +858,9 @@ public class ApiClient {
|
||||
}
|
||||
|
||||
if (matchCounter > 1 && "oneOf".equals(schema.getSchemaType())) {// more than 1 match for oneOf
|
||||
throw new ApiException("Response body is invalid as it matches more than one schema (" + String.join(", ", matchSchemas) + ") defined in the oneOf model: " + schema.getClass().getName());
|
||||
throw new ApiException("Response body is invalid as it matches more than one schema (" + StringUtil.join(matchSchemas, ", ") + ") defined in the oneOf model: " + schema.getClass().getName());
|
||||
} else if (matchCounter == 0) { // fail to match any in oneOf/anyOf schemas
|
||||
throw new ApiException("Response body is invalid as it doens't match any schemas (" + String.join(", ", schema.getSchemas().keySet()) + ") defined in the oneOf/anyOf model: " + schema.getClass().getName());
|
||||
throw new ApiException("Response body is invalid as it doens't match any schemas (" + StringUtil.join(schema.getSchemas().keySet(), ", ") + ") defined in the oneOf/anyOf model: " + schema.getClass().getName());
|
||||
} else { // only one matched
|
||||
schema.setActualInstance(result);
|
||||
return schema;
|
||||
@@ -889,29 +975,35 @@ public class ApiClient {
|
||||
* @return The response body in type of string
|
||||
* @throws ApiException API exception
|
||||
*/
|
||||
public <T> ApiResponse<T> invokeAPI(String operation, String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, String> cookieParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames, GenericType<T> returnType, AbstractOpenApiSchema schema) throws ApiException {
|
||||
public <T> ApiResponse<T> invokeAPI(
|
||||
String operation,
|
||||
String path,
|
||||
String method,
|
||||
List<Pair> queryParams,
|
||||
Object body,
|
||||
Map<String, String> headerParams,
|
||||
Map<String, String> cookieParams,
|
||||
Map<String, Object> formParams,
|
||||
String accept,
|
||||
String contentType,
|
||||
String[] authNames,
|
||||
GenericType<T> returnType,
|
||||
AbstractOpenApiSchema schema)
|
||||
throws ApiException {
|
||||
|
||||
// Not using `.target(targetURL).path(path)` below,
|
||||
// to support (constant) query string in `path`, e.g. "/posts?draft=1"
|
||||
String targetURL;
|
||||
if (serverIndex != null) {
|
||||
Integer index;
|
||||
List<ServerConfiguration> serverConfigurations;
|
||||
Map<String, String> variables;
|
||||
|
||||
if (operationServers.containsKey(operation)) {
|
||||
index = operationServerIndex.getOrDefault(operation, serverIndex);
|
||||
variables = operationServerVariables.getOrDefault(operation, serverVariables);
|
||||
serverConfigurations = operationServers.get(operation);
|
||||
} else {
|
||||
index = serverIndex;
|
||||
variables = serverVariables;
|
||||
serverConfigurations = servers;
|
||||
}
|
||||
if (operationServers.containsKey(operation)) {
|
||||
Integer index = operationServerIndex.containsKey(operation) ? operationServerIndex.get(operation) : serverIndex;
|
||||
Map<String, String> variables = operationServerVariables.containsKey(operation) ?
|
||||
operationServerVariables.get(operation) : serverVariables;
|
||||
List<ServerConfiguration> serverConfigurations = operationServers.get(operation);
|
||||
if (index < 0 || index >= serverConfigurations.size()) {
|
||||
throw new ArrayIndexOutOfBoundsException(String.format(
|
||||
"Invalid index %d when selecting the host settings. Must be less than %d", index, serverConfigurations.size()
|
||||
));
|
||||
throw new ArrayIndexOutOfBoundsException(
|
||||
String.format(
|
||||
"Invalid index %d when selecting the host settings. Must be less than %d",
|
||||
index, serverConfigurations.size()));
|
||||
}
|
||||
targetURL = serverConfigurations.get(index).URL(variables) + path;
|
||||
} else {
|
||||
@@ -929,13 +1021,6 @@ public class ApiClient {
|
||||
|
||||
Invocation.Builder invocationBuilder = target.request().accept(accept);
|
||||
|
||||
for (Entry<String, String> entry : headerParams.entrySet()) {
|
||||
String value = entry.getValue();
|
||||
if (value != null) {
|
||||
invocationBuilder = invocationBuilder.header(entry.getKey(), value);
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry<String, String> entry : cookieParams.entrySet()) {
|
||||
String value = entry.getValue();
|
||||
if (value != null) {
|
||||
@@ -950,63 +1035,63 @@ public class ApiClient {
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry<String, String> entry : defaultHeaderMap.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (!headerParams.containsKey(key)) {
|
||||
String value = entry.getValue();
|
||||
if (value != null) {
|
||||
invocationBuilder = invocationBuilder.header(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Entity<?> entity = serialize(body, formParams, contentType);
|
||||
|
||||
// put all headers in one place
|
||||
Map<String, String> allHeaderParams = new HashMap<>();
|
||||
allHeaderParams.putAll(defaultHeaderMap);
|
||||
Map<String, String> allHeaderParams = new HashMap<>(defaultHeaderMap);
|
||||
allHeaderParams.putAll(headerParams);
|
||||
|
||||
|
||||
// update different parameters (e.g. headers) for authentication
|
||||
updateParamsForAuth(authNames, queryParams, allHeaderParams, cookieParams, serializeToString(body, formParams, contentType), method, target.getUri());
|
||||
updateParamsForAuth(
|
||||
authNames,
|
||||
queryParams,
|
||||
allHeaderParams,
|
||||
cookieParams,
|
||||
serializeToString(body, formParams, contentType),
|
||||
method,
|
||||
target.getUri());
|
||||
|
||||
for (Entry<String, String> entry : allHeaderParams.entrySet()) {
|
||||
String value = entry.getValue();
|
||||
if (value != null) {
|
||||
invocationBuilder = invocationBuilder.header(entry.getKey(), value);
|
||||
}
|
||||
}
|
||||
|
||||
Response response = null;
|
||||
|
||||
try {
|
||||
if ("GET".equals(method)) {
|
||||
response = invocationBuilder.get();
|
||||
} else if ("POST".equals(method)) {
|
||||
response = invocationBuilder.post(entity);
|
||||
} else if ("PUT".equals(method)) {
|
||||
response = invocationBuilder.put(entity);
|
||||
} else if ("DELETE".equals(method)) {
|
||||
response = invocationBuilder.method("DELETE", entity);
|
||||
} else if ("PATCH".equals(method)) {
|
||||
response = invocationBuilder.method("PATCH", entity);
|
||||
} else if ("HEAD".equals(method)) {
|
||||
response = invocationBuilder.head();
|
||||
} else if ("OPTIONS".equals(method)) {
|
||||
response = invocationBuilder.options();
|
||||
} else if ("TRACE".equals(method)) {
|
||||
response = invocationBuilder.trace();
|
||||
} else {
|
||||
throw new ApiException(500, "unknown method type " + method);
|
||||
response = sendRequest(method, invocationBuilder, entity);
|
||||
|
||||
// If OAuth is used and a status 401 is received, renew the access token and retry the request
|
||||
if (response.getStatusInfo() == Status.UNAUTHORIZED) {
|
||||
for (String authName : authNames) {
|
||||
Authentication authentication = authentications.get(authName);
|
||||
if (authentication instanceof OAuth) {
|
||||
OAuth2AccessToken accessToken = ((OAuth) authentication).renewAccessToken();
|
||||
if (accessToken != null) {
|
||||
invocationBuilder.header("Authorization", null);
|
||||
invocationBuilder.header("Authorization", "Bearer " + accessToken.getAccessToken());
|
||||
response = sendRequest(method, invocationBuilder, entity);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int statusCode = response.getStatusInfo().getStatusCode();
|
||||
Map<String, List<String>> responseHeaders = buildResponseHeaders(response);
|
||||
|
||||
if (response.getStatus() == Status.NO_CONTENT.getStatusCode()) {
|
||||
return new ApiResponse<>(statusCode, responseHeaders);
|
||||
if (response.getStatusInfo() == Status.NO_CONTENT) {
|
||||
return new ApiResponse<T>(statusCode, responseHeaders);
|
||||
} else if (response.getStatusInfo().getFamily() == Status.Family.SUCCESSFUL) {
|
||||
if (returnType == null)
|
||||
return new ApiResponse<>(statusCode, responseHeaders);
|
||||
else
|
||||
if (schema == null) {
|
||||
return new ApiResponse<>(statusCode, responseHeaders, deserialize(response, returnType));
|
||||
} else { // oneOf/anyOf
|
||||
return new ApiResponse<>(statusCode, responseHeaders, (T)deserializeSchemas(response, schema));
|
||||
}
|
||||
if (returnType == null) return new ApiResponse<T>(statusCode, responseHeaders);
|
||||
else if (schema == null) {
|
||||
return new ApiResponse<T>(statusCode, responseHeaders, deserialize(response, returnType));
|
||||
} else { // oneOf/anyOf
|
||||
return new ApiResponse<T>(
|
||||
statusCode, responseHeaders, (T) deserializeSchemas(response, schema));
|
||||
}
|
||||
} else {
|
||||
String message = "error";
|
||||
String respBody = null;
|
||||
@@ -1019,20 +1104,34 @@ public class ApiClient {
|
||||
}
|
||||
}
|
||||
throw new ApiException(
|
||||
response.getStatus(),
|
||||
message,
|
||||
buildResponseHeaders(response),
|
||||
respBody);
|
||||
response.getStatus(), message, buildResponseHeaders(response), respBody);
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
response.close();
|
||||
} catch (Exception e) {
|
||||
// it's not critical, since the response object is local in method invokeAPI; that's fine, just continue
|
||||
// it's not critical, since the response object is local in method invokeAPI; that's fine,
|
||||
// just continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Response sendRequest(String method, Invocation.Builder invocationBuilder, Entity<?> entity) {
|
||||
Response response;
|
||||
if ("POST".equals(method)) {
|
||||
response = invocationBuilder.post(entity);
|
||||
} else if ("PUT".equals(method)) {
|
||||
response = invocationBuilder.put(entity);
|
||||
} else if ("DELETE".equals(method)) {
|
||||
response = invocationBuilder.method("DELETE", entity);
|
||||
} else if ("PATCH".equals(method)) {
|
||||
response = invocationBuilder.method("PATCH", entity);
|
||||
} else {
|
||||
response = invocationBuilder.method(method);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Add qualified name of the operation as a first parameter.
|
||||
*/
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.openapitools.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -58,4 +61,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,27 +15,169 @@ package org.openapitools.client.auth;
|
||||
|
||||
import org.openapitools.client.Pair;
|
||||
import org.openapitools.client.ApiException;
|
||||
import com.github.scribejava.core.builder.ServiceBuilder;
|
||||
import com.github.scribejava.core.builder.api.DefaultApi20;
|
||||
import com.github.scribejava.core.exceptions.OAuthException;
|
||||
import com.github.scribejava.core.model.OAuth2AccessToken;
|
||||
import com.github.scribejava.core.oauth.OAuth20Service;
|
||||
|
||||
import javax.ws.rs.core.UriBuilder;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
public class OAuth implements Authentication {
|
||||
private String accessToken;
|
||||
private static final Logger log = Logger.getLogger(OAuth.class.getName());
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
private String tokenUrl;
|
||||
private String absoluteTokenUrl;
|
||||
private OAuthFlow flow = OAuthFlow.application;
|
||||
private OAuth20Service service;
|
||||
private DefaultApi20 authApi;
|
||||
private String scope;
|
||||
private String username;
|
||||
private String password;
|
||||
private String code;
|
||||
private volatile OAuth2AccessToken accessToken;
|
||||
|
||||
public OAuth(String basePath, String tokenUrl) {
|
||||
this.tokenUrl = tokenUrl;
|
||||
this.absoluteTokenUrl = createAbsoluteTokenUrl(basePath, tokenUrl);
|
||||
authApi = new DefaultApi20() {
|
||||
@Override
|
||||
public String getAccessTokenEndpoint() {
|
||||
return absoluteTokenUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getAuthorizationBaseUrl() {
|
||||
throw new UnsupportedOperationException("Shouldn't get there !");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
private static String createAbsoluteTokenUrl(String basePath, String tokenUrl) {
|
||||
if (!URI.create(tokenUrl).isAbsolute()) {
|
||||
try {
|
||||
return UriBuilder.fromPath(basePath).path(tokenUrl).build().toURL().toString();
|
||||
} catch (MalformedURLException e) {
|
||||
log.log(Level.SEVERE, "Couldn't create absolute token URL", e);
|
||||
}
|
||||
}
|
||||
return tokenUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyToParams(List<Pair> queryParams, Map<String, String> headerParams, Map<String, String> cookieParams, String payload, String method, URI uri) throws ApiException {
|
||||
public void applyToParams(
|
||||
List<Pair> queryParams,
|
||||
Map<String, String> headerParams,
|
||||
Map<String, String> cookieParams,
|
||||
String payload,
|
||||
String method,
|
||||
URI uri)
|
||||
throws ApiException {
|
||||
|
||||
if (accessToken == null) {
|
||||
obtainAccessToken(null);
|
||||
}
|
||||
if (accessToken != null) {
|
||||
headerParams.put("Authorization", "Bearer " + accessToken);
|
||||
headerParams.put("Authorization", "Bearer " + accessToken.getAccessToken());
|
||||
}
|
||||
}
|
||||
|
||||
public OAuth2AccessToken renewAccessToken() throws ApiException {
|
||||
String refreshToken = null;
|
||||
if (accessToken != null) {
|
||||
refreshToken = accessToken.getRefreshToken();
|
||||
accessToken = null;
|
||||
}
|
||||
return obtainAccessToken(refreshToken);
|
||||
}
|
||||
|
||||
public synchronized OAuth2AccessToken obtainAccessToken(String refreshToken) throws ApiException {
|
||||
if (service == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
if (refreshToken != null) {
|
||||
return service.refreshAccessToken(refreshToken);
|
||||
}
|
||||
} catch (OAuthException | InterruptedException | ExecutionException | IOException e) {
|
||||
log.log(Level.FINE, "Refreshing the access token using the refresh token failed", e);
|
||||
}
|
||||
try {
|
||||
switch (flow) {
|
||||
case password:
|
||||
if (username != null && password != null) {
|
||||
accessToken = service.getAccessTokenPasswordGrant(username, password, scope);
|
||||
}
|
||||
break;
|
||||
case accessCode:
|
||||
if (code != null) {
|
||||
accessToken = service.getAccessToken(code);
|
||||
code = null;
|
||||
}
|
||||
break;
|
||||
case application:
|
||||
accessToken = service.getAccessTokenClientCredentialsGrant(scope);
|
||||
}
|
||||
} catch (OAuthException | InterruptedException | ExecutionException | IOException e) {
|
||||
throw new ApiException(e);
|
||||
}
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public OAuth2AccessToken getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public OAuth setAccessToken(OAuth2AccessToken accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuth setAccessToken(String accessToken) {
|
||||
this.accessToken = new OAuth2AccessToken(accessToken);
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuth setScope(String scope) {
|
||||
this.scope = scope;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuth setCredentials(String clientId, String clientSecret) {
|
||||
service = new ServiceBuilder(clientId)
|
||||
.apiSecret(clientSecret)
|
||||
.build(authApi);
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuth usePasswordFlow(String username, String password) {
|
||||
this.flow = OAuthFlow.password;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuth useAuthorizationCodeFlow(String code) {
|
||||
this.flow = OAuthFlow.accessCode;
|
||||
this.code = code;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OAuth setFlow(OAuthFlow flow) {
|
||||
this.flow = flow;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setBasePath(String basePath) {
|
||||
this.absoluteTokenUrl = createAbsoluteTokenUrl(basePath, tokenUrl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.openapitools.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -58,4 +61,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.openapitools.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -58,4 +61,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.openapitools.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -58,4 +61,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.openapitools.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -58,4 +61,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.openapitools.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -58,4 +61,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.openapitools.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -58,4 +61,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.openapitools.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -58,4 +61,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.openapitools.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -58,4 +61,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.openapitools.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -58,4 +61,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.openapitools.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -58,4 +61,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.openapitools.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -58,4 +61,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.openapitools.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -58,4 +61,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.openapitools.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -58,4 +61,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.openapitools.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -58,4 +61,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
|
||||
package org.openapitools.client;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
/**
|
||||
@@ -58,4 +61,23 @@ public class StringUtil {
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a list of strings with the given separator.
|
||||
*
|
||||
* @param list The list of strings
|
||||
* @param separator The separator
|
||||
* @return the resulting string
|
||||
*/
|
||||
public static String join(Collection<String> list, String separator) {
|
||||
Iterator<String> iterator = list.iterator();
|
||||
StringBuilder out = new StringBuilder();
|
||||
if (iterator.hasNext()) {
|
||||
out.append(iterator.next());
|
||||
}
|
||||
while (iterator.hasNext()) {
|
||||
out.append(separator).append(iterator.next());
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user