1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.atlassian.jira.rest.client.internal.json;
18
19 import com.atlassian.jira.rest.client.ExpandableProperty;
20 import com.atlassian.jira.rest.client.RestClientException;
21 import com.atlassian.jira.rest.client.domain.BasicUser;
22 import org.codehaus.jettison.json.JSONArray;
23 import org.codehaus.jettison.json.JSONException;
24 import org.codehaus.jettison.json.JSONObject;
25 import org.joda.time.DateTime;
26 import org.joda.time.format.DateTimeFormatter;
27 import org.joda.time.format.ISODateTimeFormat;
28
29 import javax.annotation.Nullable;
30 import java.net.URI;
31 import java.net.URISyntaxException;
32 import java.util.ArrayList;
33 import java.util.Collection;
34
35 public class JsonParseUtil {
36 private static final DateTimeFormatter DATE_TIME_FORMATTER = ISODateTimeFormat.dateTime();
37 private static final DateTimeFormatter DATE_FORMATTER = ISODateTimeFormat.date();
38 public static final String VALUE_KEY = "value";
39 public static final String SELF_ATTR = "self";
40
41
42
43
44
45 public static <T> Collection<T> parseJsonArray(JSONArray jsonArray, JsonParser<T> jsonParser) throws JSONException {
46 final Collection<T> res = new ArrayList<T>(jsonArray.length());
47 for (int i = 0; i < jsonArray.length(); i++) {
48 res.add(jsonParser.parse(jsonArray.getJSONObject(i)));
49 }
50 return res;
51 }
52
53 public static <T> ExpandableProperty<T> parseExpandableProperty(JSONObject json, JsonParser<T> expandablePropertyBuilder)
54 throws JSONException {
55 final int numItems = json.getInt("size");
56 final Collection<T> items;
57 JSONArray itemsJa = json.getJSONArray("items");
58
59 if (itemsJa.length() > 0) {
60 items = new ArrayList<T>(numItems);
61 for (int i = 0; i < itemsJa.length(); i++) {
62 final T item = expandablePropertyBuilder.parse(itemsJa.getJSONObject(i));
63 items.add(item);
64 }
65 } else {
66 items = null;
67 }
68
69 return new ExpandableProperty<T>(numItems, items);
70 }
71
72
73
74 public static URI getSelfUri(JSONObject jsonObject) throws JSONException {
75 return parseURI(jsonObject.getString(SELF_ATTR));
76 }
77
78 public static JSONObject getNestedObject(JSONObject json, String... path) throws JSONException {
79 for (String s : path) {
80 json = json.getJSONObject(s);
81 }
82 return json;
83 }
84
85 @Nullable
86 public static JSONObject getNestedOptionalObject(JSONObject json, String... path) throws JSONException {
87 for (int i = 0; i < path.length - 1; i++) {
88 String s = path[i];
89 json = json.getJSONObject(s);
90 }
91 return json.optJSONObject(path[path.length - 1]);
92 }
93
94
95 public static JSONArray getNestedArray(JSONObject json, String... path) throws JSONException {
96 for (int i = 0; i < path.length - 1; i++) {
97 String s = path[i];
98 json = json.getJSONObject(s);
99 }
100 return json.getJSONArray(path[path.length - 1]);
101 }
102
103 public static JSONArray getNestedOptionalArray(JSONObject json, String... path) throws JSONException {
104 for (int i = 0; json != null && i < path.length - 1; i++) {
105 String s = path[i];
106 json = json.optJSONObject(s);
107 }
108 return json == null ? null : json.optJSONArray(path[path.length - 1]);
109 }
110
111
112 public static String getNestedString(JSONObject json, String... path) throws JSONException {
113
114 for (int i = 0; i < path.length - 1; i++) {
115 String s = path[i];
116 json = json.getJSONObject(s);
117 }
118 return json.getString(path[path.length - 1]);
119 }
120
121 public static boolean getNestedBoolean(JSONObject json, String... path) throws JSONException {
122
123 for (int i = 0; i < path.length - 1; i++) {
124 String s = path[i];
125 json = json.getJSONObject(s);
126 }
127 return json.getBoolean(path[path.length - 1]);
128 }
129
130
131 public static URI parseURI(String str) {
132 try {
133 return new URI(str);
134 } catch (URISyntaxException e) {
135 throw new RestClientException(e);
136 }
137 }
138
139 @Nullable
140 public static URI parseOptionalURI(JSONObject jsonObject, String attributeName) {
141 final String s = getOptionalString(jsonObject, attributeName);
142 return s != null ? parseURI(s) : null;
143 }
144
145 @Nullable
146 public static BasicUser parseBasicUser(@Nullable JSONObject json) throws JSONException {
147 if (json == null) {
148 return null;
149 }
150 final String username = json.getString("name");
151 if (!json.has(JsonParseUtil.SELF_ATTR) && "Anonymous".equals(username)) {
152 return null;
153 }
154 return new BasicUser(getSelfUri(json), username, json.optString("displayName", null));
155 }
156
157 public static DateTime parseDateTime(JSONObject jsonObject, String attributeName) throws JSONException {
158 return parseDateTime(jsonObject.getString(attributeName));
159 }
160
161 @Nullable
162 public static DateTime parseOptionalDateTime(JSONObject jsonObject, String attributeName) throws JSONException {
163 final String s = getOptionalString(jsonObject, attributeName);
164 return s != null ? parseDateTime(s) : null;
165 }
166
167 public static DateTime parseDateTime(String str) {
168 try {
169 return DATE_TIME_FORMATTER.parseDateTime(str);
170 } catch (Exception e) {
171 throw new RestClientException(e);
172 }
173 }
174
175 public static DateTime parseDate(String str) {
176 try {
177 return DATE_FORMATTER.parseDateTime(str);
178 } catch (Exception e) {
179 throw new RestClientException(e);
180 }
181 }
182
183 public static String format(DateTime dateTime) {
184 return DATE_FORMATTER.print(dateTime);
185 }
186
187
188 @Nullable
189 public static String getNullableString(JSONObject jsonObject, String attributeName) throws JSONException {
190 final Object o = jsonObject.get(attributeName);
191 if (o == JSONObject.NULL) {
192 return null;
193 }
194 return o.toString();
195 }
196
197
198 @Nullable
199 public static String getOptionalString(JSONObject jsonObject, String attributeName) {
200 final Object res = jsonObject.opt(attributeName);
201 if (res == JSONObject.NULL || res == null) {
202 return null;
203 }
204 return res.toString();
205 }
206
207 @Nullable
208 public static JSONObject getOptionalJsonObject(JSONObject jsonObject, String attributeName) {
209 final JSONObject res = jsonObject.optJSONObject(attributeName);
210 if (res == JSONObject.NULL || res == null) {
211 return null;
212 }
213 return res;
214 }
215
216
217 public static Collection<String> toStringCollection(JSONArray jsonArray) throws JSONException {
218 final ArrayList<String> res = new ArrayList<String>(jsonArray.length());
219 for (int i = 0; i < jsonArray.length(); i++) {
220 res.add(jsonArray.getString(i));
221 }
222 return res;
223 }
224
225 public static Integer parseOptionInteger(JSONObject json, final String attributeName) throws JSONException {
226 return json.has(attributeName) ? json.getInt(attributeName) : null;
227 }
228
229 @Nullable
230 public static Long getOptionalLong(JSONObject jsonObject, String attributeName) throws JSONException {
231 return jsonObject.has(attributeName) ? jsonObject.getLong(attributeName) : null;
232 }
233 }