001package com.plivo.api.models.base;
002
003import com.fasterxml.jackson.annotation.JsonAutoDetect;
004import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
005import com.fasterxml.jackson.annotation.JsonIgnore;
006import com.fasterxml.jackson.databind.JsonNode;
007import com.plivo.api.Plivo;
008import com.plivo.api.PlivoClient;
009import com.plivo.api.exceptions.AuthenticationException;
010import com.plivo.api.exceptions.InvalidRequestException;
011import com.plivo.api.exceptions.PlivoRestException;
012import com.plivo.api.exceptions.ResourceNotFoundException;
013import com.plivo.api.exceptions.ServerException;
014import java.io.IOException;
015import java.lang.reflect.InvocationTargetException;
016import java.lang.reflect.Method;
017import java.util.HashMap;
018import okhttp3.ResponseBody;
019import retrofit2.Response;
020
021// Needed because we use fluent style APIs
022@JsonAutoDetect(fieldVisibility = Visibility.ANY)
023public abstract class BaseRequest<T extends BaseResource> {
024  @JsonIgnore
025  protected PlivoClient plivoClient = Plivo.getClient();
026
027  public PlivoClient client() {
028      return this.plivoClient;
029  }
030
031  public BaseRequest client(final PlivoClient plivoClient) {
032    this.plivoClient = plivoClient;
033    return this;
034  }
035
036  protected void validate() {
037    if (plivoClient == null) {
038      throw new IllegalStateException("client cannot be null");
039    }
040
041    // Convenient way to test setters and getters
042    if (plivoClient.isTesting()) {
043      HashMap<String, Object> values = new HashMap<>();
044      for (Method method : this.getClass().getMethods()) {
045        if (method.getParameterCount() == 0) {
046          String methodName = method.getName();
047          try {
048            this.getClass().getDeclaredField(methodName);
049            values.put(methodName, method.invoke(this));
050          } catch (NoSuchFieldException | SecurityException | IllegalAccessException | InvocationTargetException e) {
051            //nop
052          }
053        }
054      }
055      for (Method method : this.getClass().getMethods()) {
056        if (method.getParameterCount() == 1) {
057          String methodName = method.getName();
058          try {
059            this.getClass().getDeclaredField(methodName);
060            Object value = values.get(methodName);
061            method.invoke(this, value);
062          } catch (NoSuchFieldException | SecurityException | IllegalAccessException | InvocationTargetException e) {
063            //nop
064          }
065        }
066      }
067    }
068  }
069
070  protected void handleResponse(Response response) throws PlivoRestException, IOException {
071    if (plivoClient.isTesting()) {
072      if (response.body() != null) {
073        if (!(response.body() instanceof ResponseBody)) {
074          client().getObjectMapper().convertValue(response.body(), JsonNode.class);
075        }
076        //noinspection ResultOfMethodCallIgnored
077        response.body().toString();
078      }
079    }
080
081    int responseCode = response.code();
082    switch (responseCode) {
083      case 400:
084        throw new InvalidRequestException(response.errorBody().string());
085      case 401:
086        throw new AuthenticationException(response.errorBody().string());
087      case 404:
088        throw new ResourceNotFoundException(response.errorBody().string());
089      case 405:
090        throw new InvalidRequestException(response.errorBody().string());
091      case 500:
092        throw new ServerException(response.errorBody().string());
093    }
094
095    if (this instanceof Deleter && responseCode != 204) {
096      throw new PlivoRestException(response.errorBody().string());
097    }
098
099    if (!response.isSuccessful()) {
100      throw new PlivoRestException(response.errorBody().string());
101    }
102  }
103}