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