OSDN Git Service

commit java sdk doc and source code
[bytom/bytom-java-sdk.git] / src / main / java / io / bytom / http / BatchResponse.java
1 package io.bytom.http;
2
3 import io.bytom.exception.*;
4 import com.google.gson.Gson;
5 import com.google.gson.JsonArray;
6 import com.google.gson.JsonElement;
7 import com.google.gson.JsonParser;
8 import com.squareup.okhttp.Response;
9
10 import java.io.IOException;
11 import java.lang.reflect.Type;
12 import java.util.*;
13
14 /**
15  * BatchResponse provides a convenient interface for handling the results of
16  * batched API calls. The response contains one success or error per outgoing
17  * request item in the batch. Errors are always of type APIExcpetion.
18  */
19 public class BatchResponse<T> {
20   private Response response;
21   private Map<Integer, T> successesByIndex = new LinkedHashMap<>();
22   private Map<Integer, APIException> errorsByIndex = new LinkedHashMap<>();
23
24   /**
25    * This constructor is used when deserializing a response from an API call.
26    */
27   public BatchResponse(Response response, Gson serializer, Type tClass, Type eClass)
28       throws BytomException, IOException {
29     this.response = response;
30
31     try {
32       JsonArray root = new JsonParser().parse(response.body().charStream()).getAsJsonArray();
33       for (int i = 0; i < root.size(); i++) {
34         JsonElement elem = root.get(i);
35
36         // Test for interleaved errors
37         APIException err = serializer.fromJson(elem, eClass);
38         if (err.code != null) {
39           errorsByIndex.put(i, err);
40           continue;
41         }
42
43         successesByIndex.put(i, (T) serializer.fromJson(elem, tClass));
44       }
45     } catch (IllegalStateException e) {
46       throw new JSONException(
47           "Unable to read body: " + e.getMessage(), response.headers().get("Chain-Request-ID"));
48     }
49   }
50
51   /**
52    * This constructor is used for synthetically generating a batch response
53    * object from a map of successes and a map of errors. It ensures that
54    * the successes and errors are stored in an order-preserving fashion.
55    */
56   public BatchResponse(Map<Integer, T> successes, Map<Integer, APIException> errors) {
57     List<Integer> successIndexes = new ArrayList<>();
58     Iterator<Integer> successIter = successes.keySet().iterator();
59     while (successIter.hasNext()) successIndexes.add(successIter.next());
60     Collections.sort(successIndexes);
61     for (int i : successIndexes) successesByIndex.put(i, successes.get(i));
62
63     List<Integer> errorIndexes = new ArrayList<>();
64     Iterator<Integer> errorIter = errors.keySet().iterator();
65     while (errorIter.hasNext()) errorIndexes.add(errorIter.next());
66     Collections.sort(errorIndexes);
67     for (int i : errorIndexes) errorsByIndex.put(i, errors.get(i));
68   }
69
70   /**
71    * Returns the internal response object.
72    */
73   public Response response() {
74     return response;
75   }
76
77   /**
78    * Returns the total number of response objects. This should equal the number
79    * of request objects in the batch.
80    */
81   public int size() {
82     return successesByIndex.size() + errorsByIndex.size();
83   }
84
85   /**
86    * Returns whether the request object at the given index produced a success.
87    * @param index the index of the request object
88    */
89   public boolean isSuccess(int index) {
90     return successesByIndex.containsKey(index);
91   }
92
93   /**
94    * Returns whether the request object at the given index produced an error.
95    * @param index the index of the request object
96    */
97   public boolean isError(int index) {
98     return errorsByIndex.containsKey(index);
99   }
100
101   /**
102    * Returns a list of successful response objects in the batch. The order of
103    * the list corresponds to the order of the request objects that produced the
104    * successes.
105    */
106   public List<T> successes() {
107     List<T> res = new ArrayList<>();
108     res.addAll(successesByIndex.values());
109     return res;
110   }
111
112   /**
113    * Returns a list of error objects in the batch. The order of the list
114    * corresponds to the order of the request objects that produced the
115    * errors.
116    */
117   public List<APIException> errors() {
118     List<APIException> res = new ArrayList<>();
119     res.addAll(errorsByIndex.values());
120     return res;
121   }
122
123   /**
124    * Returns a map of success responses, keyed by the index of the request
125    * object that produced the success. The set of this map's keys is mutually
126    * exclusive of the keys returned by errorsByIndex.
127    */
128   public Map<Integer, T> successesByIndex() {
129     return successesByIndex;
130   }
131
132   /**
133    * Returns a map of error responses, keyed by the index of the request
134    * object that produced the error. The set of this map's keys is mutually
135    * exclusive of the keys returned by successByIndex.
136    */
137   public Map<Integer, APIException> errorsByIndex() {
138     return errorsByIndex;
139   }
140 }