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.PlivoValidationException;
007import com.plivo.api.exceptions.IterableError;
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 MessagingBrandLister<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 MessagingBrandLister<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   * @return Denotes the number of value items by which the results should be offset.                    
047   */                                                                                                    
048  public Integer offset() {                                                                              
049    return this.offset;                                                                                  
050  }                                                                                                      
051                                                                                                         
052  /**                                                                                                    
053   * @param limit Used to display the number of results per page. The maximum number of results that     
054   *              can be fetched is 20.                                                                  
055   */                                                                                                    
056  public MessagingBrandLister<T> limit(final Integer limit) {                                                     
057    this.limit = limit;                                                                                  
058    return this;                                                                                         
059  }                                                                                                      
060                                                                                                         
061  /**                                                                                                    
062   * @param offset Denotes the number of value items by which the results should be offset.              
063   */                                                                                                    
064  public MessagingBrandLister<T> offset(final Integer offset) {                                                   
065    this.offset = offset;                                                                                
066    return this;                                                                                         
067  }                                                                                                      
068                                                                                                         
069  protected abstract Call<ListResponse<T>> obtainCall() throws PlivoValidationException;            
070                                                                                                         
071  /**                                                                                               
072   * Actually list instances of the resource.                                                       
073   */                                                                                               
074  public ListResponse<T> list() throws IOException, PlivoRestException, PlivoValidationException {
075    validate();                                                                                        
076    Response<ListResponse<T>> response = obtainCall().execute();                                  
077                                                                                                       
078    handleResponse(response);                                                                          
079                                                                                                       
080    return response.body();                                                                            
081  }                                                                                                    
082                                                                                                       
083  protected Map<String, Object> toMap() {                                                                
084    client();                                                                                            
085    return Utils.objectToMap(plivoClient.getObjectMapper(), this);                                       
086  }                                                                                                      
087                                                                                                         
088  @Override                                                                                              
089  public Iterator<T> iterator() throws IterableError {                                                   
090    if (limit == null) {                                                                                 
091      limit = 20;                                                                                        
092    }                                                                                                    
093                                                                                                         
094    if (offset == null) {                                                                                
095      offset = 0;                                                                                        
096    }                                                                                                    
097                                                                                                         
098    return new Iterator<T>() {                                                                           
099      Deque<T> items = new ConcurrentLinkedDeque<>();                                                    
100                                                                                                         
101      @Override                                                                                          
102      public boolean hasNext() {                                                                         
103        if (!items.isEmpty()) {                                                                          
104          return true;                                                                                   
105        }                                                                                                
106                                                                                                         
107        try {                                                                                            
108          ListResponse<T> itemList = MessagingBrandLister.this.list();                                       
109          if (itemList.getBrands().isEmpty()) {                                                     
110            return false;                                                                              
111          }                                                                                            
112          this.items.addAll(itemList.getBrands());                                                  
113          offset += limit;                                                                             
114        } catch (IOException | PlivoRestException | PlivoValidationException exception) {              
115          throw new IterableError();                                                                   
116        }                                                                                              
117        return true;                                                                                   
118      }
119      @Override                                                                                        
120      public T next() {                                                                                
121        if (items.isEmpty()) {                                                                         
122          try {                                                                                        
123            ListResponse<T> itemList = MessagingBrandLister.this.list();                                   
124            this.items.addAll(itemList.getBrands());                                                
125            offset += limit;                                                                           
126          } catch (IOException | PlivoRestException | PlivoValidationException exception) {            
127            throw new IterableError();                                                                 
128          }                                                                                            
129        }                                                                                              
130                                                                                                       
131        return items.removeFirst();                                                                    
132      }                                                                                                
133    };                                                                                                 
134  }                                                                                                    
135}