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 org.apache.log4j.Logger;
23
24 import java.util.HashMap;
25 import java.util.Map;
26
27
28
29
30
31
32 public class GraphField {
33 protected static final Logger LOGGER = Logger.getLogger("davmail.exchange.graph.GraphField");
34
35 @SuppressWarnings({"UnusedDeclaration"})
36 protected enum PropertyType {
37 ApplicationTime, ApplicationTimeArray, Binary, BinaryArray, Boolean, CLSID, CLSIDArray, Currency, CurrencyArray,
38 Double, DoubleArray, Error, Float, FloatArray, Integer, IntegerArray, Long, LongArray, Null, Object,
39 ObjectArray, Short, ShortArray, SystemTime, SystemTimeArray, String, StringArray
40 }
41
42 @SuppressWarnings({"UnusedDeclaration"})
43 public enum DistinguishedPropertySetType {
44 Meeting, Appointment, Common, PublicStrings, Address, InternetHeaders, CalendarAssistant, UnifiedMessaging, Task
45 }
46
47 private static final Map<String, GraphField> FIELD_MAP = new HashMap<>();
48
49 static {
50 addFieldMap("id");
51
52
53 addFieldMap("folderlastmodified", 0x3008, PropertyType.SystemTime);
54 addFieldMap("folderclass", 0x3613, PropertyType.String);
55 addFieldMap("ctag", 0x670a, PropertyType.SystemTime);
56 addFieldMap("uidNext", 0x6751, PropertyType.Integer);
57
58
59 addFieldMap("isRead", PropertyType.Boolean);
60 addFieldMap("isDraft");
61 addFieldMap("receivedDateTime", PropertyType.SystemTime);
62 addFieldMap("datereceived", "receivedDateTime", PropertyType.SystemTime);
63 addFieldMap("date", "receivedDateTime", PropertyType.SystemTime);
64
65
66
67
68 addFieldMap("deliverytime", 0x0e06, PropertyType.SystemTime);
69 addFieldMap("clientsubmittime", 0x0039, PropertyType.SystemTime);
70 addFieldMap("inreplyto", 0x1042, PropertyType.String);
71 addFieldMap("references", 0x1039, PropertyType.String);
72 addFieldMap("lastmodified", "lastModifiedDateTime", PropertyType.SystemTime);
73
74
75 addFieldMap("uid", 0x0FF9, PropertyType.Binary);
76 addFieldMap("messageFlags", 0x0e07, PropertyType.Integer);
77 addFieldMap("imapUid", 0x0e23, PropertyType.Integer);
78 addFieldMap("messageSize", 0x0e08, PropertyType.Integer);
79 addFieldMap("etag", 0x3008, PropertyType.SystemTime);
80 addFieldMap("contentclass", DistinguishedPropertySetType.InternetHeaders, "content-class");
81 addFieldMap("iconIndex", 0x1080, PropertyType.Integer);
82
83 addFieldMap("keywords", "categories", PropertyType.StringArray);
84 addFieldMap( "categories", PropertyType.StringArray);
85
86 addFieldMap("@odata.etag");
87 addFieldMap("changeKey", "@odata.etag");
88
89 addFieldMap("read", "isRead", PropertyType.Boolean);
90 addFieldMap("messageheaders", 0x007D, PropertyType.String);
91 addFieldMap("internetMessageHeaders");
92
93 addFieldMap("to", DistinguishedPropertySetType.InternetHeaders, "to");
94 addFieldMap("cc", DistinguishedPropertySetType.InternetHeaders, "cc");
95 addFieldMap("from", DistinguishedPropertySetType.InternetHeaders, "from");
96
97 addFieldMap("permanenturl", 0x670E, PropertyType.String);
98 addFieldMap("lastVerbExecuted", 0x1081, PropertyType.Integer);
99 addFieldMap("junk", 0x1083, PropertyType.Integer);
100 addFieldMap("flagStatus", 0x1090, PropertyType.Integer);
101 addFieldMap("deleted", DistinguishedPropertySetType.Common, 0x8570, PropertyType.Integer);
102
103 addFieldMap("urlcompname", 0x10f3, PropertyType.String);
104
105
106
107 addFieldMap("processed", 0x65e8, PropertyType.Boolean);
108
109 addFieldMap("instancetype", DistinguishedPropertySetType.PublicStrings, "urn:schemas:calendar:instancetype", PropertyType.Integer);
110
111
112 addFieldMap("dtstamp", DistinguishedPropertySetType.Meeting, 0x001A, PropertyType.SystemTime);
113
114 addFieldMap("iCalUid");
115 addFieldMap("calendaruid", DistinguishedPropertySetType.PublicStrings, "urn:schemas:calendar:uid", PropertyType.String);
116
117 addFieldMap("isrecurring", DistinguishedPropertySetType.Appointment, 0x8223, PropertyType.Boolean);
118
119 addFieldMap("dtstart", "start");
120 addFieldMap("dtend", "end");
121 addFieldMap("subject");
122 addFieldMap("status");
123 addFieldMap("taskstatus");
124 addFieldMap("importance");
125 addFieldMap("createdDateTime", "createdDateTime", PropertyType.SystemTime);
126 addFieldMap("lastModifiedDateTime", "lastModifiedDateTime", PropertyType.SystemTime);
127
128
129 addFieldMap("summary", "title");
130 addFieldMap("dueDateTime");
131 addFieldMap("startDateTime");
132 addFieldMap("completedDateTime");
133 addFieldMap("datecompleted", "completedDateTime");
134 addFieldMap("objecttype");
135
136 addFieldMap("originalStartTimeZone");
137
138 addFieldMap("allowNewTimeProposals");
139 addFieldMap("attendees");
140 addFieldMap("bodyPreview");
141 addFieldMap("body");
142 addFieldMap("end");
143 addFieldMap("exceptionOccurrences");
144 addFieldMap("cancelledOccurrences");
145 addFieldMap("hasAttachments");
146 addFieldMap("isOnlineMeeting");
147 addFieldMap("onlineMeeting");
148 addFieldMap("isOrganizer");
149 addFieldMap("location");
150 addFieldMap("locations");
151 addFieldMap("organizer");
152 addFieldMap("originalStart");
153 addFieldMap("recurrence");
154 addFieldMap("reminderMinutesBeforeStart");
155 addFieldMap("start");
156 addFieldMap("type");
157
158 addFieldMap("iCalUId");
159 addFieldMap("transactionId");
160
161
162 addFieldMap("showAs");
163 addFieldMap("isAllDay", "isAllDay", PropertyType.Boolean);
164 addFieldMap("isCancelled", "isCancelled", PropertyType.Boolean);
165 addFieldMap("responseRequested");
166 addFieldMap("responseStatus");
167
168 addFieldMap("isReminderOn", "isReminderOn", PropertyType.Boolean);
169
170 addFieldMap("xmozsendinvitations", DistinguishedPropertySetType.PublicStrings, "xmozsendinvitations");
171 addFieldMap("xmozlastack", DistinguishedPropertySetType.PublicStrings, "xmozlastack");
172 addFieldMap("xmozsnoozetime", DistinguishedPropertySetType.PublicStrings, "xmozsnoozetime");
173
174
175 addFieldMap("displayname", "displayName");
176
177 addFieldMap("outlookmessageclass", 0x001A, PropertyType.String);
178 addFieldMap("fileas", "fileAs");
179
180 addFieldMap("cn", "displayName");
181 addFieldMap("sn", "surname");
182 addFieldMap("givenName", "givenName");
183 addFieldMap("middlename", "middleName");
184 addFieldMap("personaltitle", "title");
185 addFieldMap("title", "jobTitle");
186
187
188 addFieldMap("description", 0x1000, PropertyType.String);
189 addFieldMap("personalNotes");
190
191
192 addFieldMap("notes");
193 addFieldMap("displayName");
194
195 addFieldMap("namesuffix", "generation");
196 addFieldMap("nickname", "nickName");
197 addFieldMap("mobile", 0x3A1C, PropertyType.String);
198 addFieldMap("telephoneNumber", 0x3A08, PropertyType.String);
199
200 addFieldMap("otherBusinessTelephoneNumber", 0x3A1B, PropertyType.String);
201
202 addFieldMap("facsimiletelephonenumber", 0x3A24, PropertyType.String);
203 addFieldMap("pager", 0x3A21, PropertyType.String);
204
205 addFieldMap("homeCity", 0x3A59, PropertyType.String);
206 addFieldMap("homeCountry", 0x3A5A, PropertyType.String);
207 addFieldMap("homePhone", 0x3A09, PropertyType.String);
208
209 addFieldMap("otherHomePhone", 0x3A2F, PropertyType.String);
210
211 addFieldMap("homePostalCode", 0x3A5B, PropertyType.String);
212 addFieldMap("homeState", 0x3A5C, PropertyType.String);
213 addFieldMap("homeStreet", 0x3A5D, PropertyType.String);
214 addFieldMap("homepostofficebox", 0x3A5E, PropertyType.String);
215
216 addFieldMap("postofficebox", DistinguishedPropertySetType.Address, 0x804A, PropertyType.String);
217 addFieldMap("roomnumber", "officeLocation");
218 addFieldMap("street", DistinguishedPropertySetType.Address, 0x8045, PropertyType.String);
219
220 addFieldMap("l", DistinguishedPropertySetType.Address, 0x8046, PropertyType.String);
221 addFieldMap("st", DistinguishedPropertySetType.Address, 0x8047, PropertyType.String);
222 addFieldMap("postalcode", DistinguishedPropertySetType.Address, 0x8048, PropertyType.String);
223 addFieldMap("co", DistinguishedPropertySetType.Address, 0x8049, PropertyType.String);
224
225
226
227 addFieldMap("o", "companyName");
228
229 addFieldMap("department", "department");
230
231 addFieldMap("smtpemail1", DistinguishedPropertySetType.Address, 0x8083, PropertyType.String);
232 addFieldMap("smtpemail2", DistinguishedPropertySetType.Address, 0x8093, PropertyType.String);
233 addFieldMap("smtpemail3", DistinguishedPropertySetType.Address, 0x80A3, PropertyType.String);
234
235 addFieldMap("businesshomepage", 0x3A51, PropertyType.String);
236 addFieldMap("personalHomePage", 0x3A50, PropertyType.String);
237
238
239 addFieldMap("extensionattribute1", DistinguishedPropertySetType.Address, 0x804F, PropertyType.String);
240 addFieldMap("extensionattribute2", DistinguishedPropertySetType.Address, 0x8050, PropertyType.String);
241 addFieldMap("extensionattribute3", DistinguishedPropertySetType.Address, 0x8051, PropertyType.String);
242 addFieldMap("extensionattribute4", DistinguishedPropertySetType.Address, 0x8052, PropertyType.String);
243
244 addFieldMap("bday", "birthday", PropertyType.SystemTime);
245 addFieldMap("anniversary", "weddingAnniversary", PropertyType.SystemTime);
246
247 addFieldMap("otherstreet", 0x3A63, PropertyType.String);
248 addFieldMap("otherstate", 0x3A62, PropertyType.String);
249 addFieldMap("otherpostofficebox", 0x3A64, PropertyType.String);
250 addFieldMap("otherpostalcode", 0x3A61, PropertyType.String);
251 addFieldMap("othercountry", 0x3A60, PropertyType.String);
252 addFieldMap("othercity", 0x3A5F, PropertyType.String);
253
254 addFieldMap("secretarycn", "assistantName");
255 addFieldMap("spousecn", "spouseName");
256
257 addFieldMap("private", DistinguishedPropertySetType.Common, 0x8506, PropertyType.Boolean);
258
259 addFieldMap("im", DistinguishedPropertySetType.Address, 0x8062, PropertyType.String);
260 addFieldMap("fburl", DistinguishedPropertySetType.Address, 0x80D8, PropertyType.String);
261
262 addFieldMap("haspicture", DistinguishedPropertySetType.Address, 0x8015, PropertyType.Boolean);
263
264 addFieldMap("manager");
265 addFieldMap("profession");
266
267 addFieldMap("othermobile", 0x3A1E, PropertyType.String);
268 addFieldMap("otherTelephone", 0x3A1F, PropertyType.String);
269
270 addFieldMap("homefax", 0x3A25, PropertyType.String);
271 addFieldMap("internationalisdnnumber", 0x3A2D, PropertyType.String);
272
273 addFieldMap("gender");
274
275 addFieldMap("sensitivity", 0x0036, PropertyType.Integer);
276
277
278 addFieldMap("class", "sensitivity");
279
280
281 addFieldMap("msexchangecertificate");
282 addFieldMap("usersmimecertificate");
283
284 }
285
286 protected static void addFieldMap(String alias, GraphField field) {
287 if (FIELD_MAP.containsKey(alias)) {
288 throw new IllegalArgumentException("Duplicate field alias: " + alias);
289 }
290 FIELD_MAP.put(alias, field);
291 }
292
293 protected static void addFieldMap(String alias) {
294 addFieldMap(alias, new GraphField(alias));
295 }
296
297 protected static void addFieldMap(String alias, String graphId) {
298 addFieldMap(alias, new GraphField(alias, graphId));
299 }
300
301 protected static void addFieldMap(String alias, PropertyType propertyType) {
302 addFieldMap(alias, new GraphField(alias, alias, propertyType));
303 }
304
305 protected static void addFieldMap(String alias, String graphId, PropertyType propertyType) {
306 addFieldMap(alias, new GraphField(alias, graphId, propertyType));
307 }
308
309 protected static void addFieldMap(String alias, int intPropertyTag, PropertyType propertyType) {
310 addFieldMap(alias, new GraphField(alias, intPropertyTag, propertyType));
311 }
312
313 protected static void addFieldMap(String alias, DistinguishedPropertySetType distinguishedPropertySetId, int intPropertyTag, PropertyType propertyType) {
314 addFieldMap(alias, new GraphField(alias, distinguishedPropertySetId, intPropertyTag, propertyType));
315 }
316
317 protected static void addFieldMap(String alias, DistinguishedPropertySetType distinguishedPropertySetId, String propertyName, PropertyType propertyType) {
318 addFieldMap(alias, new GraphField(alias, distinguishedPropertySetId, propertyName, propertyType));
319 }
320
321 protected static void addFieldMap(String alias, DistinguishedPropertySetType distinguishedPropertySetId, String propertyName) {
322 addFieldMap(alias, new GraphField(alias, distinguishedPropertySetId, propertyName));
323 }
324
325 protected String alias;
326 protected String graphId;
327
328 protected DistinguishedPropertySetType distinguishedPropertySetId;
329
330 protected String propertyName;
331 protected int propertyId;
332 protected String propertyTag;
333 protected PropertyType propertyType;
334
335
336 private boolean extended = false;
337
338
339
340
341
342 public GraphField(String alias) {
343 this.alias = alias;
344 this.graphId = alias;
345 }
346
347 public GraphField(String alias, String graphId) {
348 this.alias = alias;
349 this.graphId = graphId;
350 }
351
352
353 protected GraphField(String alias, String graphId, PropertyType propertyType) {
354 this.alias = alias;
355 this.graphId = graphId;
356 this.propertyType = propertyType;
357 }
358
359
360
361
362
363
364 public GraphField(String alias, DistinguishedPropertySetType distinguishedPropertySetId, String propertyName) {
365 this.extended = true;
366
367 this.alias = alias;
368 this.propertyType = PropertyType.String;
369 this.distinguishedPropertySetId = distinguishedPropertySetId;
370 this.propertyName = propertyName;
371 this.graphId = buildGraphId();
372 }
373
374
375
376
377
378
379
380
381 protected GraphField(String alias, int intPropertyTag, PropertyType propertyType) {
382 this.extended = true;
383
384 this.alias = alias;
385 this.propertyTag = "0x" + Integer.toHexString(intPropertyTag);
386 this.propertyType = propertyType;
387 this.graphId = buildGraphId();
388 }
389
390 protected GraphField(String alias, DistinguishedPropertySetType distinguishedPropertySetId, int propertyId, PropertyType propertyType) {
391 this.extended = true;
392
393 this.alias = alias;
394 this.distinguishedPropertySetId = distinguishedPropertySetId;
395 this.propertyType = propertyType;
396 this.propertyId = propertyId;
397 this.graphId = buildGraphId();
398 }
399
400 protected GraphField(String alias, DistinguishedPropertySetType distinguishedPropertySetId, String propertyName, PropertyType propertyType) {
401 this.extended = true;
402
403 this.alias = alias;
404 this.distinguishedPropertySetId = distinguishedPropertySetId;
405 this.propertyName = propertyName;
406 this.propertyType = propertyType;
407 this.graphId = buildGraphId();
408 }
409
410
411
412
413
414
415
416
417
418 private String buildGraphId() {
419
420
421
422 String namespaceGuid = null;
423 if (distinguishedPropertySetId != null) {
424 switch (distinguishedPropertySetId) {
425 case PublicStrings:
426 namespaceGuid = "{00020329-0000-0000-c000-000000000046}";
427 break;
428 case InternetHeaders:
429 namespaceGuid = "{00020386-0000-0000-c000-000000000046}";
430 break;
431 case Common:
432 namespaceGuid = "{00062008-0000-0000-c000-000000000046}";
433 break;
434 case Address:
435 namespaceGuid = "{00062004-0000-0000-c000-000000000046}";
436 break;
437 case Appointment:
438 namespaceGuid = "{00062002-0000-0000-C000-000000000046}";
439 break;
440 case Meeting:
441 namespaceGuid = "{6ED8DA90-450B-101B-98DA-00AA003F1305}";
442 break;
443 case Task:
444 namespaceGuid = "{00062003-0000-0000-c000-000000000046}";
445 break;
446 }
447 }
448
449
450 StringBuilder buffer = new StringBuilder();
451 if (namespaceGuid != null) {
452 buffer.append(propertyType.name()).append(" ").append(namespaceGuid);
453 if (propertyName != null) {
454 buffer.append(" Name ").append(propertyName);
455 } else {
456 buffer.append(" Id ").append("0x").append(Integer.toHexString(propertyId));
457 }
458 } else if (propertyTag != null) {
459 buffer.append(propertyType.name()).append(" ").append(propertyTag);
460 }
461 return buffer.toString();
462 }
463
464 public boolean isExtended() {
465 return extended;
466 }
467
468 public String getAlias() {
469 return alias;
470 }
471
472 public String getGraphId() {
473 if (graphId != null) {
474 return graphId;
475 }
476 throw new IllegalStateException("Graph id not set on field " + alias);
477
478 }
479
480 public boolean isMultiValued() {
481 return propertyType == PropertyType.StringArray;
482 }
483
484 public boolean isNumber() {
485 return propertyType == PropertyType.Short || propertyType == PropertyType.Integer || propertyType == PropertyType.Long || propertyType == PropertyType.Double;
486 }
487
488 public boolean isBinary() {
489 return propertyType == PropertyType.Binary;
490 }
491
492 public boolean isBoolean() {
493 return propertyType == PropertyType.Boolean;
494 }
495
496 public boolean isDate() {
497 return propertyType == PropertyType.SystemTime;
498 }
499
500 public boolean isInternetHeaders() {
501 return distinguishedPropertySetId == DistinguishedPropertySetType.InternetHeaders;
502 }
503
504
505
506
507
508
509 public static GraphField get(String alias) {
510 if (!FIELD_MAP.containsKey(alias)) {
511 LOGGER.warn("Missing mapping for " + alias);
512 return new GraphField(alias);
513 }
514 return FIELD_MAP.get(alias);
515 }
516
517 public static String getGraphId(String alias) {
518 return get(alias).getGraphId();
519 }
520
521 }