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.Settings;
23 import davmail.exchange.ExchangeSession;
24 import davmail.util.IOUtil;
25 import davmail.util.StringUtil;
26 import org.apache.http.client.methods.HttpDelete;
27 import org.apache.http.client.methods.HttpGet;
28 import org.apache.http.client.methods.HttpPatch;
29 import org.apache.http.client.methods.HttpPost;
30 import org.apache.http.client.methods.HttpPut;
31 import org.apache.http.client.methods.HttpRequestBase;
32 import org.apache.http.client.utils.URIBuilder;
33 import org.apache.http.entity.ByteArrayEntity;
34 import org.apache.log4j.Logger;
35 import org.codehaus.jettison.json.JSONException;
36 import org.codehaus.jettison.json.JSONObject;
37
38 import java.io.IOException;
39 import java.net.URISyntaxException;
40 import java.util.ArrayList;
41 import java.util.HashMap;
42 import java.util.List;
43 import java.util.Map;
44 import java.util.Set;
45
46
47
48
49 public class GraphRequestBuilder {
50 protected static final Logger LOGGER = Logger.getLogger("davmail.exchange.graph.GraphRequestBuilder");
51
52 String method = "POST";
53 String url;
54
55 String contentType = "application/json";
56
57 String baseUrl = Settings.getGraphUrl();
58 String version = Settings.getProperty("davmail.graphVersion", "beta");
59 String mailbox;
60 String objectType;
61
62 String objectId;
63
64 String childType;
65 String childId;
66 String childSuffix;
67
68 String action;
69
70 String select;
71 String expand;
72
73 String filter;
74 String orderBy;
75 String search;
76
77 int sizeLimit;
78
79 int maxPageSize;
80
81 String deltaToken;
82
83 String startDateTime;
84 String endDateTime;
85
86 String timeZone;
87
88 Set<GraphField> selectFields;
89
90 String accessToken;
91
92 JSONObject jsonBody = null;
93
94
95
96
97 HashMap<String, String> headerMap;
98
99 byte[] mimeContent;
100
101
102
103
104
105
106
107 public GraphRequestBuilder setProperty(String name, String value) throws JSONException {
108 if (jsonBody == null) {
109 jsonBody = new JSONObject();
110 }
111 jsonBody.put(name, value);
112 return this;
113 }
114
115
116
117
118
119 public GraphRequestBuilder setJsonBody(JSONObject jsonBody) {
120 this.jsonBody = jsonBody;
121 return this;
122 }
123
124 public GraphRequestBuilder setJsonBody(GraphObject graphObject) {
125 this.jsonBody = graphObject.jsonObject;
126 return this;
127 }
128
129 public GraphRequestBuilder addHeader(String name, String value) {
130 if (headerMap == null) {
131 headerMap = new HashMap<>();
132 }
133 headerMap.put(name, value);
134 return this;
135 }
136
137 public GraphRequestBuilder setUrl(String url) {
138 this.url = url;
139 return this;
140 }
141
142
143
144
145
146
147 public GraphRequestBuilder setSelectFields(Set<GraphField> selectFields) {
148 this.selectFields = selectFields;
149 computeSelectAndExpand();
150 return this;
151 }
152
153 public GraphRequestBuilder setVersion(String version) {
154 this.version = version;
155 return this;
156 }
157
158 public GraphRequestBuilder setObjectType(String objectType) {
159 this.objectType = objectType;
160 return this;
161 }
162
163 public GraphRequestBuilder setChildType(String childType) {
164 this.childType = childType;
165 return this;
166 }
167
168 public GraphRequestBuilder setChildId(String childId) {
169 this.childId = childId;
170 return this;
171 }
172
173 public GraphRequestBuilder setChildSuffix(String childSuffix) {
174 this.childSuffix = childSuffix;
175 return this;
176 }
177
178 public GraphRequestBuilder setAction(String action) {
179 this.action = action;
180 return this;
181 }
182
183 public GraphRequestBuilder setFilter(String filter) {
184 this.filter = filter;
185 return this;
186 }
187
188 public GraphRequestBuilder setFilter(ExchangeSession.Condition condition) {
189 if (condition != null && !condition.isEmpty()) {
190 StringBuilder buffer = new StringBuilder();
191 condition.appendTo(buffer);
192 this.filter = buffer.toString();
193 LOGGER.debug("filter: " + filter);
194 }
195 return this;
196 }
197
198 public GraphRequestBuilder setSearch(String search) {
199 this.search = search;
200 return this;
201 }
202
203 public GraphRequestBuilder setOrderBy(String orderBy) {
204 this.orderBy = orderBy;
205 return this;
206 }
207
208 public GraphRequestBuilder setStartDateTime(String startDateTime) {
209 this.startDateTime = startDateTime;
210 return this;
211 }
212
213 public GraphRequestBuilder setEndDateTime(String endDateTime) {
214 this.endDateTime = endDateTime;
215 return this;
216 }
217
218 public GraphRequestBuilder setTimezone(String timeZone) {
219 this.timeZone = timeZone;
220 return this;
221 }
222
223 public GraphRequestBuilder setAccessToken(String accessToken) {
224 this.accessToken = accessToken;
225 return this;
226 }
227
228 public GraphRequestBuilder setMethod(String method) {
229 this.method = method;
230 return this;
231 }
232
233 public GraphRequestBuilder setContentType(String contentType) {
234 this.contentType = contentType;
235 return this;
236 }
237
238 public GraphRequestBuilder setMimeContent(byte[] mimeContent) {
239 this.mimeContent = mimeContent;
240 return this;
241 }
242
243 public GraphRequestBuilder setMailbox(String mailbox) {
244 this.mailbox = mailbox;
245 return this;
246 }
247
248 public GraphRequestBuilder setObjectId(String objectId) {
249 this.objectId = objectId;
250 return this;
251 }
252
253 public GraphRequestBuilder setSelect(String select) {
254 this.select = select;
255 return this;
256 }
257
258 public GraphRequestBuilder setExpand(String expand) {
259 this.expand = expand;
260 return this;
261 }
262
263 public GraphRequestBuilder setSizeLimit(int sizeLimit) {
264 this.sizeLimit = sizeLimit;
265 return this;
266 }
267
268 public GraphRequestBuilder setMaxPageSize(int maxPageSize) {
269 this.maxPageSize = maxPageSize;
270 return this;
271 }
272
273 public GraphRequestBuilder setDeltaToken(String deltaToken) {
274 this.deltaToken = deltaToken;
275 return this;
276 }
277
278
279
280
281
282
283 protected String buildPath() {
284 StringBuilder buffer = new StringBuilder();
285 buffer.append("/").append(version);
286 if ("orgcontacts".equals(objectType)) {
287
288 buffer.append("/contacts");
289 } else if ("users".equals(objectType)) {
290 buffer.append("/users");
291 } else {
292 if (mailbox != null) {
293 buffer.append("/users/").append(mailbox);
294 } else {
295 buffer.append("/me");
296 }
297 if (objectType != null) {
298 buffer.append("/").append(objectType);
299 }
300 }
301 if (objectId != null) {
302 buffer.append("/").append(objectId);
303 }
304 if (childType != null) {
305 buffer.append("/").append(childType);
306 }
307 if (childId != null) {
308 buffer.append("/").append(childId);
309 }
310 if (childSuffix != null) {
311 buffer.append("/").append(childSuffix);
312 }
313 if (action != null) {
314 buffer.append("/").append(action);
315 }
316
317 return buffer.toString();
318 }
319
320
321
322
323 private void computeSelectAndExpand() {
324 ArrayList<String> singleValueProperties = new ArrayList<>();
325 ArrayList<String> multiValueProperties = new ArrayList<>();
326 ArrayList<String> selectProperties = new ArrayList<>();
327 for (GraphField field : selectFields) {
328 if (field.isExtended()) {
329 if (field.isMultiValued()) {
330 multiValueProperties.add(field.getGraphId());
331 } else {
332 singleValueProperties.add(field.getGraphId());
333 if (field.getAlias().startsWith("smtpemail")) {
334
335 selectProperties.add("emailAddresses");
336 }
337 }
338
339 } else if (!GraphField.getGraphId("@odata.etag").equals(field.getGraphId())){
340 selectProperties.add(field.getGraphId());
341 }
342 }
343 StringBuilder expandBuffer = new StringBuilder();
344 if (!singleValueProperties.isEmpty()) {
345 expandBuffer.append("singleValueExtendedProperties($filter=");
346 appendExpandProperties(expandBuffer, singleValueProperties);
347 expandBuffer.append(")");
348 }
349 if (!multiValueProperties.isEmpty()) {
350 if (!singleValueProperties.isEmpty()) {
351 expandBuffer.append(",");
352 }
353 expandBuffer.append("multiValueExtendedProperties($filter=");
354 appendExpandProperties(expandBuffer, multiValueProperties);
355 expandBuffer.append(")");
356 }
357 expand = expandBuffer.toString();
358 if (!selectProperties.isEmpty()) {
359 select = String.join(",", selectProperties);
360 }
361 }
362
363
364
365
366
367
368 protected void appendExpandProperties(StringBuilder buffer, List<String> properties) {
369 boolean first = true;
370 for (String id : properties) {
371 if (first) {
372 first = false;
373 } else {
374 buffer.append(" or ");
375 }
376 buffer.append("id eq '").append(id).append("'");
377 }
378 }
379
380
381
382
383
384
385
386 public HttpRequestBase build() throws IOException {
387 try {
388
389 String requestUrl = url;
390 if (requestUrl == null) {
391 URIBuilder uriBuilder = new URIBuilder(baseUrl).setPath(buildPath());
392 if (select != null) {
393 uriBuilder.addParameter("$select", select);
394 }
395
396 if (expand != null && !expand.isEmpty()) {
397 uriBuilder.addParameter("$expand", expand);
398 }
399
400 if (filter != null) {
401 uriBuilder.addParameter("$filter", filter);
402 }
403
404 if (orderBy != null) {
405 uriBuilder.addParameter("$orderby", orderBy);
406 }
407
408 if (search != null) {
409 uriBuilder.addParameter("$search", "\"" + StringUtil.escapeDoubleQuotes(search) + "\"");
410 }
411
412 if (startDateTime != null) {
413 uriBuilder.addParameter("startDateTime", startDateTime);
414 }
415
416 if (endDateTime != null) {
417 uriBuilder.addParameter("endDateTime", endDateTime);
418 }
419
420 if (sizeLimit != 0) {
421 uriBuilder.addParameter("$top", String.valueOf(sizeLimit));
422 }
423 if (deltaToken != null) {
424 uriBuilder.addParameter("$deltatoken", deltaToken);
425 }
426 requestUrl = uriBuilder.toString();
427 }
428
429 HttpRequestBase httpRequest;
430
431 if ("POST".equals(method)) {
432 httpRequest = new HttpPost(requestUrl);
433 if (mimeContent != null) {
434 ((HttpPost) httpRequest).setEntity(new ByteArrayEntity(mimeContent));
435 } else if (jsonBody != null) {
436 ((HttpPost) httpRequest).setEntity(new ByteArrayEntity(IOUtil.convertToBytes(jsonBody)));
437 }
438 } else if (HttpPut.METHOD_NAME.equals(method)) {
439
440 httpRequest = new HttpPut(requestUrl);
441 if (mimeContent != null) {
442 ((HttpPut) httpRequest).setEntity(new ByteArrayEntity(mimeContent));
443 }
444 } else if (HttpPatch.METHOD_NAME.equals(method)) {
445 httpRequest = new HttpPatch(requestUrl);
446 if (jsonBody != null) {
447 ((HttpPatch) httpRequest).setEntity(new ByteArrayEntity(IOUtil.convertToBytes(jsonBody)));
448 }
449 } else if ("DELETE".equals(method)) {
450 httpRequest = new HttpDelete(requestUrl);
451 } else {
452
453 httpRequest = new HttpGet(requestUrl);
454 }
455 httpRequest.setHeader("Content-Type", contentType);
456 httpRequest.setHeader("Authorization", "Bearer " + accessToken);
457
458
459 if (headerMap != null) {
460 for (Map.Entry<String, String> header : headerMap.entrySet()) {
461 httpRequest.addHeader(header.getKey(), header.getValue());
462 }
463 }
464
465 if (maxPageSize != 0) {
466 httpRequest.addHeader("Prefer", "odata.maxpagesize=" + maxPageSize);
467 }
468
469 if (timeZone != null) {
470 httpRequest.addHeader("Prefer", "outlook.timezone=\"" + timeZone + "\"");
471 }
472
473 httpRequest.addHeader("Prefer", "IdType=\"ImmutableId\"");
474
475 if (LOGGER.isDebugEnabled()) {
476 LOGGER.debug(httpRequest.getMethod() + " " + httpRequest.getURI());
477 if (jsonBody != null) {
478 LOGGER.debug(jsonBody.toString());
479 }
480 }
481
482 return httpRequest;
483 } catch (URISyntaxException e) {
484 throw new IOException(e.getMessage(), e);
485 }
486 }
487
488 }