1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package davmail.exchange.graph;
21
22 import davmail.exception.DavMailException;
23 import davmail.exchange.VProperty;
24 import davmail.util.DateUtil;
25 import davmail.util.StringUtil;
26 import org.apache.log4j.Logger;
27 import org.codehaus.jettison.json.JSONArray;
28 import org.codehaus.jettison.json.JSONException;
29 import org.codehaus.jettison.json.JSONObject;
30
31 import java.text.ParseException;
32 import java.text.SimpleDateFormat;
33 import java.util.Date;
34 import java.util.HashSet;
35 import java.util.ResourceBundle;
36 import java.util.TimeZone;
37
38 import static davmail.util.DateUtil.CALDAV_DATE_TIME;
39 import static davmail.util.DateUtil.GRAPH_DATE_TIME;
40
41
42
43
44 public class GraphObject {
45 protected static final Logger LOGGER = Logger.getLogger(GraphObject.class);
46
47 protected final JSONObject jsonObject;
48 protected int statusCode;
49
50 public GraphObject(JSONObject jsonObject) {
51 this.jsonObject = jsonObject;
52 }
53
54 public String optString(String key) {
55
56 return optString(GraphField.get(key));
57 }
58
59 public String optString(GraphField field) {
60 String key = field.getGraphId();
61 if (key == null) {
62 return null;
63 }
64 String value = null;
65
66 if ("keywords".equals(key) || "categories".equals(key)) {
67 JSONArray categoriesArray = jsonObject.optJSONArray("categories");
68 HashSet<String> keywords = new HashSet<>();
69
70 if (categoriesArray != null) {
71 for (int j = 0; j < categoriesArray.length(); j++) {
72 keywords.add(categoriesArray.optString(j));
73 }
74 value = StringUtil.join(keywords, ",");
75 }
76 } else if ("from".equals(key)) {
77 value = formatEmailAddress(jsonObject.optJSONObject(key));
78 } else if ("@odata.etag".equals(key)) {
79
80 String odataEtag = jsonObject.optString("@odata.etag");
81 if (odataEtag != null && odataEtag.startsWith("W/\"") && odataEtag.endsWith("\"")) {
82 value = odataEtag.substring(3, odataEtag.length() - 1);
83 }
84 } else if (!field.isExtended()) {
85
86 value = jsonObject.optString(key, null);
87 } else {
88 JSONArray singleValueExtendedProperties = jsonObject.optJSONArray("singleValueExtendedProperties");
89 if (singleValueExtendedProperties != null) {
90
91 for (int i = 0; i < singleValueExtendedProperties.length(); i++) {
92 JSONObject singleValueObject = singleValueExtendedProperties.optJSONObject(i);
93 if (singleValueObject != null && key.equals(singleValueObject.optString("id"))) {
94 value = singleValueObject.optString("value");
95 }
96 }
97 }
98 }
99 if (field.isDate()) {
100 try {
101 value = GraphExchangeSession.convertDateFromExchange(value);
102 } catch (DavMailException e) {
103 LOGGER.warn("Invalid date " + value + " on field " + key);
104 }
105 }
106 return value;
107 }
108
109 protected String formatEmailAddress(JSONObject jsonObject) {
110 String value = null;
111 if (jsonObject != null) {
112 JSONObject jsonEmailAddress = jsonObject.optJSONObject("emailAddress");
113 if (jsonEmailAddress != null) {
114 value = jsonEmailAddress.optString("name", "") + " <" + jsonEmailAddress.optString("address", "") + ">";
115 }
116 }
117 return value;
118 }
119
120 public JSONArray optJSONArray(String key) {
121 return jsonObject.optJSONArray(key);
122 }
123
124
125
126
127
128
129
130
131 public void put(String alias, String value) throws JSONException {
132 GraphField field = GraphField.get(alias);
133 String key = field.getGraphId();
134
135 if (field.isExtended()) {
136
137 if (field.isNumber() && value == null) {
138 value = "0";
139 }
140 if (field.isBoolean() && value == null) {
141 value = "false";
142 }
143 getSingleValueExtendedProperties().put(new JSONObject().put("id", key).put("value", value == null ? JSONObject.NULL : value));
144 } else {
145 jsonObject.put(key, value == null ? JSONObject.NULL : value);
146 }
147 }
148
149
150
151
152
153
154
155
156 public void put(String alias, boolean value) throws JSONException {
157 GraphField field = GraphField.get(alias);
158 String key = field.getGraphId();
159
160 if (field.isExtended()) {
161 getSingleValueExtendedProperties().put(new JSONObject().put("id", key).put("value", value));
162 } else {
163 jsonObject.put(key, value);
164 }
165 }
166
167 public void put(String key, JSONArray values) throws JSONException {
168 jsonObject.put(key, values);
169 }
170
171
172
173
174
175
176 public void setCategories(String values) throws JSONException {
177 if (values != null) {
178 setCategories(values.split(","));
179 } else {
180 jsonObject.put("categories", new JSONArray());
181 }
182 }
183
184 public void setCategories(String[] values) throws JSONException {
185
186 JSONArray jsonValues = new JSONArray();
187 for (String singleValue : values) {
188 jsonValues.put(singleValue);
189 }
190 jsonObject.put("categories", jsonValues);
191 }
192
193
194
195
196
197
198
199
200 protected JSONArray getSingleValueExtendedProperties() throws JSONException {
201 JSONArray singleValueExtendedProperties = jsonObject.optJSONArray("singleValueExtendedProperties");
202 if (singleValueExtendedProperties == null) {
203 singleValueExtendedProperties = new JSONArray();
204 jsonObject.put("singleValueExtendedProperties", singleValueExtendedProperties);
205 }
206 return singleValueExtendedProperties;
207 }
208
209
210
211
212
213
214
215
216 public String getString(String key) throws JSONException {
217 String value = optString(key);
218 if (value == null) {
219 throw new JSONException("JSONObject[" + key + "] not found.");
220 }
221 return value;
222 }
223
224
225
226
227
228
229
230 public String optString(String section, String key) {
231 JSONObject sectionObject = jsonObject.optJSONObject(section);
232 if (sectionObject != null) {
233 return sectionObject.optString(key, null);
234 }
235 return null;
236 }
237
238 public boolean getBoolean(String key) throws JSONException {
239 return getBoolean(GraphField.get(key));
240 }
241
242 public boolean optBoolean(String key) {
243 return optBoolean(GraphField.get(key));
244 }
245
246 public boolean getBoolean(GraphField field) throws JSONException {
247 String key = field.getGraphId();
248 if (key == null) {
249 return false;
250 }
251 return jsonObject.getBoolean(key);
252 }
253
254 public boolean optBoolean(GraphField field) {
255 String key = field.getGraphId();
256 if (key == null) {
257 return false;
258 }
259 return jsonObject.optBoolean(key);
260 }
261
262 public JSONObject optJSONObject(String key) {
263 return jsonObject.optJSONObject(key);
264 }
265
266
267
268
269
270
271
272
273
274 public Date optDateTimeTimeZone(String key) throws DavMailException {
275 JSONObject sectionObject = jsonObject.optJSONObject(key);
276 if (sectionObject != null) {
277 String timeZone = sectionObject.optString("timeZone");
278 String dateTime = sectionObject.optString("dateTime");
279 if (timeZone != null && dateTime != null) {
280 try {
281 SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSS");
282 parser.setTimeZone(TimeZone.getTimeZone(convertTimezoneFromExchange(timeZone)));
283 return parser.parse(dateTime);
284 } catch (ParseException e) {
285 throw new DavMailException("EXCEPTION_INVALID_DATE", dateTime);
286 }
287 }
288 }
289 return null;
290 }
291
292
293
294
295
296
297 public VProperty getRecurrenceId() throws DavMailException {
298
299 String originalStartTimeZone = optString("originalStartTimeZone");
300 String originalStart = optString("originalStart");
301
302 if (originalStartTimeZone != null && originalStart != null && originalStart.length() >= 19) {
303
304 VProperty recurrenceId = new VProperty("RECURRENCE-ID", DateUtil.convertDateFormat(originalStart.substring(0, 19), GRAPH_DATE_TIME, CALDAV_DATE_TIME));
305 recurrenceId.setParam("TZID", originalStartTimeZone);
306 return recurrenceId;
307 } else {
308 throw new DavMailException("LOG_MESSAGE", "Missing original start date and timezone");
309 }
310 }
311
312
313
314
315
316
317
318 public static String convertTimezoneFromExchange(String exchangeTimezone) {
319 ResourceBundle tzidsBundle = ResourceBundle.getBundle("stdtimezones");
320 if (tzidsBundle.containsKey(exchangeTimezone)) {
321 return tzidsBundle.getString(exchangeTimezone);
322 } else {
323 return exchangeTimezone;
324 }
325 }
326
327
328 public int optInt(String key) {
329 return jsonObject.optInt(key);
330 }
331
332 public String toString(int indentFactor) throws JSONException {
333 return jsonObject.toString(indentFactor);
334 }
335 }
336