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