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