001package com.plivo.api.models.base; 002 003import com.fasterxml.jackson.databind.annotation.JsonSerialize; 004import com.fasterxml.jackson.databind.annotation.JsonSerialize.Typing; 005import com.plivo.api.PlivoClient; 006import com.plivo.api.exceptions.IterableError; 007import com.plivo.api.exceptions.PlivoValidationException; 008import com.plivo.api.exceptions.PlivoRestException; 009import com.plivo.api.util.Utils; 010 011import java.io.IOException; 012import java.util.Deque; 013import java.util.Iterator; 014import java.util.Map; 015import java.util.concurrent.ConcurrentLinkedDeque; 016 017import retrofit2.Call; 018import retrofit2.Response; 019 020/** 021 * Lists instances of a resource, possibly filtered. 022 * 023 * @param <T> The type of the resource. 024 */ 025@JsonSerialize(typing = Typing.STATIC) 026public abstract class VoiceLister<T extends BaseResource> extends BaseRequest<T> implements Iterable<T> { 027 028 protected Integer limit = null; 029 protected Integer offset = null; 030 031 @Override 032 public VoiceLister<T> client(final PlivoClient plivoClient) { 033 this.plivoClient = plivoClient; 034 return this; 035 } 036 037 038 /** 039 * @return Used to display the number of results per page. The maximum number of results that can 040 * be fetched is 20. 041 */ 042 public Integer limit() { 043 return this.limit; 044 } 045 046 /** 047 * @return Denotes the number of value items by which the results should be offset. 048 */ 049 public Integer offset() { 050 return this.offset; 051 } 052 053 /** 054 * @param limit Used to display the number of results per page. The maximum number of results that 055 * can be fetched is 20. 056 */ 057 public VoiceLister<T> limit(final Integer limit) { 058 this.limit = limit; 059 return this; 060 } 061 062 /** 063 * @param offset Denotes the number of value items by which the results should be offset. 064 */ 065 public VoiceLister<T> offset(final Integer offset) { 066 this.offset = offset; 067 return this; 068 } 069 070 protected abstract Call<ListResponse<T>> obtainCall() throws PlivoValidationException; 071 protected abstract Call<ListResponse<T>> obtainFallback1Call() throws PlivoValidationException; 072 protected abstract Call<ListResponse<T>> obtainFallback2Call() throws PlivoValidationException; 073 074 /** 075 * Actually list instances of the resource. 076 */ 077 public ListResponse<T> list() throws IOException, PlivoRestException, PlivoValidationException { 078 validate(); 079 Response<ListResponse<T>> response = obtainCall().execute(); 080 081 if(response.code()>=500){ 082 response = obtainFallback1Call().execute(); 083 if(response.code()>=500){ 084 response = obtainFallback2Call().execute(); 085 } 086 } 087 088 handleResponse(response); 089 090 return response.body(); 091 } 092 093 public Long get() throws IOException, PlivoRestException, PlivoValidationException { 094 validate(); 095 Response<ListResponse<T>> response = obtainCall().execute(); 096 097 if(response.code()>=500){ 098 response = obtainFallback1Call().execute(); 099 if(response.code()>=500){ 100 response = obtainFallback2Call().execute(); 101 } 102 } 103 104 handleResponse(response); 105 try { 106 return response.body().getMeta().getTotalCount(); 107 } catch (Exception e) { 108 return 0L; 109 } 110 } 111 112 113 protected Map<String, Object> toMap() { 114 client(); 115 return Utils.objectToMap(plivoClient.getObjectMapper(), this); 116 } 117 118 @Override 119 public Iterator<T> iterator() throws IterableError { 120 if (limit == null) { 121 limit = 20; 122 } 123 124 if (offset == null) { 125 offset = 0; 126 } 127 128 return new Iterator<T>() { 129 Deque<T> items = new ConcurrentLinkedDeque<>(); 130 131 @Override 132 public boolean hasNext() { 133 if (!items.isEmpty()) { 134 return true; 135 } 136 137 try { 138 ListResponse<T> itemList = VoiceLister.this.list(); 139 if (itemList.getObjects().isEmpty()) { 140 return false; 141 } 142 this.items.addAll(itemList.getObjects()); 143 offset += limit; 144 } catch (IOException | PlivoRestException | PlivoValidationException exception) { 145 throw new IterableError(); 146 } 147 return true; 148 } 149 150 @Override 151 public T next() { 152 if (items.isEmpty()) { 153 try { 154 ListResponse<T> itemList = VoiceLister.this.list(); 155 this.items.addAll(itemList.getObjects()); 156 offset += limit; 157 } catch (IOException | PlivoRestException | PlivoValidationException exception) { 158 throw new IterableError(); 159 } 160 } 161 162 return items.removeFirst(); 163 } 164 }; 165 } 166}