Skip to content

Instantly share code, notes, and snippets.

@amardeshbd

amardeshbd/ApiClient.java

Last active Aug 23, 2016
Embed
What would you like to do?
Source Code for ApiClient.java - generated using swagger code gen tool. It uses Retrofit2 Java client library. NOTE: This file has slight modification to fix an issue detailed at https://github.com/amardeshbd/medium-api-android-sample
package io.swagger.client;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.AuthenticationRequestBuilder;
import org.apache.oltu.oauth2.client.request.OAuthClientRequest.TokenRequestBuilder;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import retrofit2.Converter;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import io.swagger.client.auth.HttpBasicAuth;
import io.swagger.client.auth.ApiKeyAuth;
import io.swagger.client.auth.OAuth;
import io.swagger.client.auth.OAuth.AccessTokenListener;
import io.swagger.client.auth.OAuthFlow;
public class ApiClient {
private Map<String, Interceptor> apiAuthorizations;
private OkHttpClient.Builder okBuilder;
private Retrofit.Builder adapterBuilder;
public ApiClient() {
apiAuthorizations = new LinkedHashMap<String, Interceptor>();
createDefaultAdapter();
}
public ApiClient(String[] authNames) {
this();
for(String authName : authNames) {
Interceptor auth;
if (authName == "OauthSecurity") {
auth = new OAuth(OAuthFlow.accessCode, "https://medium.com/m/oauth/authorize", "https://medium.com/v1/tokens", "basicProfile, listPublications, publishPost, uploadImage");
} else if (authName == "BearerToken") {
auth = new ApiKeyAuth("header", "Authorization");
} else {
throw new RuntimeException("auth name \"" + authName + "\" not found in available auth names");
}
addAuthorization(authName, auth);
}
}
/**
* 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")
.registerTypeAdapter(DateTime.class, new DateTimeTypeAdapter())
.registerTypeAdapter(LocalDate.class, new LocalDateTypeAdapter())
.create();
okBuilder = new OkHttpClient.Builder();
// [DEV NOTE: Added custom code to add interceptors for authorizations]
for (Map.Entry<String, Interceptor> entry : apiAuthorizations.entrySet()) {
okBuilder.addInterceptor(entry.getValue());
}
String baseUrl = "https://api.medium.com/v1";
if(!baseUrl.endsWith("/"))
baseUrl = baseUrl + "/";
adapterBuilder = new Retrofit
.Builder()
.baseUrl(baseUrl)
.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;
}
}
}
/**
* 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 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);
}
}
/**
* This wrapper is to take care of this case:
* when the deserialization fails due to JsonParseException and the
* 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;
}
@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);
}
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);
}
@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);
}
}
/**
* Gson TypeAdapter for Joda DateTime type
*/
class DateTimeTypeAdapter extends TypeAdapter<DateTime> {
private final DateTimeFormatter formatter = 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 DateTime read(JsonReader in) throws IOException {
switch (in.peek()) {
case NULL:
in.nextNull();
return null;
default:
String date = in.nextString();
return formatter.parseDateTime(date);
}
}
}
/**
* Gson TypeAdapter for Joda LocalDate type
*/
class LocalDateTypeAdapter extends TypeAdapter<LocalDate> {
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 LocalDate read(JsonReader in) throws IOException {
switch (in.peek()) {
case NULL:
in.nextNull();
return null;
default:
String date = in.nextString();
return formatter.parseLocalDate(date);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment