001/*
002 * The MIT License
003 * Copyright (c) 2012 Microsoft Corporation
004 *
005 * Permission is hereby granted, free of charge, to any person obtaining a copy
006 * of this software and associated documentation files (the "Software"), to deal
007 * in the Software without restriction, including without limitation the rights
008 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
009 * copies of the Software, and to permit persons to whom the Software is
010 * furnished to do so, subject to the following conditions:
011 *
012 * The above copyright notice and this permission notice shall be included in
013 * all copies or substantial portions of the Software.
014 *
015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
016 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
017 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
018 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
019 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
020 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
021 * THE SOFTWARE.
022 */
023
024package microsoft.exchange.webservices.data.core.service;
025
026import microsoft.exchange.webservices.data.core.ExchangeService;
027import microsoft.exchange.webservices.data.core.XmlElementNames;
028import microsoft.exchange.webservices.data.core.service.folder.CalendarFolder;
029import microsoft.exchange.webservices.data.core.service.folder.ContactsFolder;
030import microsoft.exchange.webservices.data.core.service.folder.Folder;
031import microsoft.exchange.webservices.data.core.service.folder.SearchFolder;
032import microsoft.exchange.webservices.data.core.service.folder.TasksFolder;
033import microsoft.exchange.webservices.data.core.service.item.Appointment;
034import microsoft.exchange.webservices.data.core.service.item.Contact;
035import microsoft.exchange.webservices.data.core.service.item.ContactGroup;
036import microsoft.exchange.webservices.data.core.service.item.Conversation;
037import microsoft.exchange.webservices.data.core.service.item.EmailMessage;
038import microsoft.exchange.webservices.data.core.service.item.Item;
039import microsoft.exchange.webservices.data.core.service.item.MeetingCancellation;
040import microsoft.exchange.webservices.data.core.service.item.MeetingMessage;
041import microsoft.exchange.webservices.data.core.service.item.MeetingRequest;
042import microsoft.exchange.webservices.data.core.service.item.MeetingResponse;
043import microsoft.exchange.webservices.data.core.service.item.PostItem;
044import microsoft.exchange.webservices.data.core.service.item.Task;
045import microsoft.exchange.webservices.data.property.complex.ItemAttachment;
046
047import java.util.ArrayList;
048import java.util.HashMap;
049import java.util.List;
050import java.util.Map;
051
052/**
053 * ServiceObjectInfo contains metadata on how to map from an element name to a
054 * ServiceObject type as well as how to map from a ServiceObject type to
055 * appropriate constructors.
056 */
057public class ServiceObjectInfo {
058
059  /**
060   * The service object constructors with attachment param.
061   */
062  private Map<Class<?>, ICreateServiceObjectWithAttachmentParam>
063      serviceObjectConstructorsWithAttachmentParam;
064
065  /**
066   * The service object constructors with service param.
067   */
068  private Map<Class<?>, ICreateServiceObjectWithServiceParam>
069      serviceObjectConstructorsWithServiceParam;
070
071  /**
072   * The xml element name to service object class map.
073   */
074  private Map<String, Class<?>> xmlElementNameToServiceObjectClassMap;
075
076  /**
077   * Default constructor.
078   */
079  public ServiceObjectInfo() {
080    this.xmlElementNameToServiceObjectClassMap =
081        new HashMap<String, Class<?>>();
082    this.serviceObjectConstructorsWithServiceParam =
083        new HashMap<Class<?>, ICreateServiceObjectWithServiceParam>();
084    this.serviceObjectConstructorsWithAttachmentParam =
085        new HashMap<Class<?>, ICreateServiceObjectWithAttachmentParam>();
086
087    this.initializeServiceObjectClassMap();
088  }
089
090  /**
091   * Initializes the service object class map. If you add a new ServiceObject
092   * subclass that can be returned by the Server, add the type to the class
093   * map as well as associated delegate(s) to call the constructor(s).
094   */
095  private void initializeServiceObjectClassMap() {
096    // Appointment
097    this.addServiceObjectType(XmlElementNames.CalendarItem,
098        Appointment.class, new ICreateServiceObjectWithServiceParam() {
099          public Object createServiceObjectWithServiceParam(
100              ExchangeService srv) throws Exception {
101            return new Appointment(srv);
102          }
103        }, new ICreateServiceObjectWithAttachmentParam() {
104          public Object createServiceObjectWithAttachmentParam(
105              ItemAttachment itemAttachment, boolean isNew)
106              throws Exception {
107            return new Appointment(itemAttachment, isNew);
108          }
109        });
110
111    // CalendarFolder
112    this.addServiceObjectType(XmlElementNames.CalendarFolder,
113        CalendarFolder.class,
114        new ICreateServiceObjectWithServiceParam() {
115          public Object createServiceObjectWithServiceParam(
116              ExchangeService srv) throws Exception {
117            return new CalendarFolder(srv);
118          }
119        }, null);
120
121    // Contact
122    this.addServiceObjectType(XmlElementNames.Contact, Contact.class,
123        new ICreateServiceObjectWithServiceParam() {
124          public Object createServiceObjectWithServiceParam(
125              ExchangeService srv) throws Exception {
126            return new Contact(srv);
127          }
128        }, new ICreateServiceObjectWithAttachmentParam() {
129          public Object createServiceObjectWithAttachmentParam(
130              ItemAttachment itemAttachment, boolean isNew)
131              throws Exception {
132            return new Contact(itemAttachment);
133          }
134        });
135
136    // ContactsFolder
137    this.addServiceObjectType(XmlElementNames.ContactsFolder,
138        ContactsFolder.class,
139        new ICreateServiceObjectWithServiceParam() {
140          public Object createServiceObjectWithServiceParam(
141              ExchangeService srv) throws Exception {
142            return new ContactsFolder(srv);
143          }
144        }, null);
145
146    // ContactGroup
147    this.addServiceObjectType(XmlElementNames.DistributionList,
148        ContactGroup.class, new ICreateServiceObjectWithServiceParam() {
149          public Object createServiceObjectWithServiceParam(
150              ExchangeService srv) throws Exception {
151            return new ContactGroup(srv);
152          }
153        }, new ICreateServiceObjectWithAttachmentParam() {
154          public Object createServiceObjectWithAttachmentParam(
155              ItemAttachment itemAttachment, boolean isNew)
156              throws Exception {
157            return new ContactGroup(itemAttachment);
158          }
159        });
160
161    // Conversation
162    this.addServiceObjectType(XmlElementNames.Conversation,
163        Conversation.class,
164        new ICreateServiceObjectWithServiceParam() {
165          public Object createServiceObjectWithServiceParam(
166              ExchangeService srv) throws Exception {
167            return new Conversation(srv);
168          }
169        }, null);
170
171    // EmailMessage
172    this.addServiceObjectType(XmlElementNames.Message, EmailMessage.class,
173        new ICreateServiceObjectWithServiceParam() {
174          public Object createServiceObjectWithServiceParam(
175              ExchangeService srv) throws Exception {
176            return new EmailMessage(srv);
177          }
178        }, new ICreateServiceObjectWithAttachmentParam() {
179          public Object createServiceObjectWithAttachmentParam(
180              ItemAttachment itemAttachment, boolean isNew)
181              throws Exception {
182            return new EmailMessage(itemAttachment);
183          }
184        });
185
186    // Folder
187    this.addServiceObjectType(XmlElementNames.Folder, Folder.class,
188        new ICreateServiceObjectWithServiceParam() {
189          public Object createServiceObjectWithServiceParam(
190              ExchangeService srv) throws Exception {
191            return new Folder(srv);
192          }
193        }, null);
194
195    // Item
196    this.addServiceObjectType(XmlElementNames.Item, Item.class,
197        new ICreateServiceObjectWithServiceParam() {
198          public Object createServiceObjectWithServiceParam(
199              ExchangeService srv) throws Exception {
200            return new Item(srv);
201          }
202        }, new ICreateServiceObjectWithAttachmentParam() {
203          public Object createServiceObjectWithAttachmentParam(
204              ItemAttachment itemAttachment, boolean isNew)
205              throws Exception {
206            return new Item(itemAttachment);
207          }
208        });
209
210    // MeetingCancellation
211    this.addServiceObjectType(XmlElementNames.MeetingCancellation,
212        MeetingCancellation.class,
213        new ICreateServiceObjectWithServiceParam() {
214          public Object createServiceObjectWithServiceParam(
215              ExchangeService srv) throws Exception {
216            return new MeetingCancellation(srv);
217          }
218        }, new ICreateServiceObjectWithAttachmentParam() {
219          public Object createServiceObjectWithAttachmentParam(
220              ItemAttachment itemAttachment, boolean isNew)
221              throws Exception {
222            return new MeetingCancellation(itemAttachment);
223          }
224        });
225
226    // MeetingMessage
227    this.addServiceObjectType(XmlElementNames.MeetingMessage,
228        MeetingMessage.class,
229        new ICreateServiceObjectWithServiceParam() {
230          public Object createServiceObjectWithServiceParam(
231              ExchangeService srv) throws Exception {
232            return new MeetingMessage(srv);
233          }
234        }, new ICreateServiceObjectWithAttachmentParam() {
235          public Object createServiceObjectWithAttachmentParam(
236              ItemAttachment itemAttachment, boolean isNew)
237              throws Exception {
238            return new MeetingMessage(itemAttachment);
239          }
240        });
241
242    // MeetingRequest
243    this.addServiceObjectType(XmlElementNames.MeetingRequest,
244        MeetingRequest.class,
245        new ICreateServiceObjectWithServiceParam() {
246          public Object createServiceObjectWithServiceParam(
247              ExchangeService srv) throws Exception {
248            return new MeetingRequest(srv);
249          }
250        }, new ICreateServiceObjectWithAttachmentParam() {
251          public Object createServiceObjectWithAttachmentParam(
252              ItemAttachment itemAttachment, boolean isNew)
253              throws Exception {
254            return new MeetingRequest(itemAttachment);
255          }
256        });
257
258    // MeetingResponse
259    this.addServiceObjectType(XmlElementNames.MeetingResponse,
260        MeetingResponse.class,
261        new ICreateServiceObjectWithServiceParam() {
262          public Object createServiceObjectWithServiceParam(
263              ExchangeService srv) throws Exception {
264            return new MeetingResponse(srv);
265          }
266        }, new ICreateServiceObjectWithAttachmentParam() {
267          public Object createServiceObjectWithAttachmentParam(
268              ItemAttachment itemAttachment, boolean isNew)
269              throws Exception {
270            return new MeetingResponse(itemAttachment);
271          }
272        });
273
274    // PostItem
275    this.addServiceObjectType(XmlElementNames.PostItem, PostItem.class,
276        new ICreateServiceObjectWithServiceParam() {
277          public Object createServiceObjectWithServiceParam(
278              ExchangeService srv) throws Exception {
279            return new PostItem(srv);
280          }
281        }, new ICreateServiceObjectWithAttachmentParam() {
282          public Object createServiceObjectWithAttachmentParam(
283              ItemAttachment itemAttachment, boolean isNew)
284              throws Exception {
285            return new PostItem(itemAttachment);
286          }
287        });
288
289    // SearchFolder
290    this.addServiceObjectType(XmlElementNames.SearchFolder,
291        SearchFolder.class, new ICreateServiceObjectWithServiceParam() {
292          public Object createServiceObjectWithServiceParam(
293              ExchangeService srv) throws Exception {
294            return new SearchFolder(srv);
295          }
296        }, null);
297
298    // Task
299    this.addServiceObjectType(XmlElementNames.Task, Task.class,
300        new ICreateServiceObjectWithServiceParam() {
301          public Object createServiceObjectWithServiceParam(
302              ExchangeService srv) throws Exception {
303            return new Task(srv);
304          }
305        }, new ICreateServiceObjectWithAttachmentParam() {
306          public Object createServiceObjectWithAttachmentParam(
307              ItemAttachment itemAttachment, boolean isNew)
308              throws Exception {
309            return new Task(itemAttachment);
310          }
311        });
312
313    // TasksFolder
314    this.addServiceObjectType(XmlElementNames.TasksFolder,
315        TasksFolder.class, new ICreateServiceObjectWithServiceParam() {
316          public Object createServiceObjectWithServiceParam(
317              ExchangeService srv) throws Exception {
318            return new TasksFolder(srv);
319          }
320        }, null);
321  }
322
323  /**
324   * Adds specified type of service object to map.
325   *
326   * @param xmlElementName                         the xml element name
327   * @param cls                                    the cls
328   * @param createServiceObjectWithServiceParam    the create service object with service param
329   * @param createServiceObjectWithAttachmentParam the create service object with attachment param
330   */
331  private void addServiceObjectType(
332      String xmlElementName,
333      Class<?> cls,
334      ICreateServiceObjectWithServiceParam createServiceObjectWithServiceParam,
335      ICreateServiceObjectWithAttachmentParam createServiceObjectWithAttachmentParam) {
336    this.xmlElementNameToServiceObjectClassMap.put(xmlElementName, cls);
337    this.serviceObjectConstructorsWithServiceParam.put(cls,
338        createServiceObjectWithServiceParam);
339    if (createServiceObjectWithAttachmentParam != null) {
340      this.serviceObjectConstructorsWithAttachmentParam.put(cls,
341          createServiceObjectWithAttachmentParam);
342    }
343  }
344
345  /**
346   * Return Dictionary that maps from element name to ServiceObject Type.
347   *
348   * @return the xml element name to service object class map
349   */
350  public Map<String, Class<?>> getXmlElementNameToServiceObjectClassMap() {
351    return this.xmlElementNameToServiceObjectClassMap;
352  }
353
354  /**
355   * Return Dictionary that maps from ServiceObject Type to
356   * CreateServiceObjectWithServiceParam delegate with ExchangeService
357   * parameter.
358   *
359   * @return the service object constructors with service param
360   */
361  public Map<Class<?>, ICreateServiceObjectWithServiceParam>
362  getServiceObjectConstructorsWithServiceParam() {
363    return this.serviceObjectConstructorsWithServiceParam;
364  }
365
366  /**
367   * Return Dictionary that maps from ServiceObject Type to
368   * CreateServiceObjectWithAttachmentParam delegate with ItemAttachment
369   * parameter.
370   *
371   * @return the service object constructors with attachment param
372   */
373  public Map<Class<?>, ICreateServiceObjectWithAttachmentParam>
374  getServiceObjectConstructorsWithAttachmentParam() {
375    return this.serviceObjectConstructorsWithAttachmentParam;
376  }
377
378  /**
379   * Set event to happen when property changed.
380   *
381   * @param change change event
382   */
383  protected void addOnChangeEvent(
384      ICreateServiceObjectWithAttachmentParam change) {
385    onChangeList.add(change);
386  }
387
388  /**
389   * Remove the event from happening when property changed.
390   *
391   * @param change change event
392   */
393  protected void removeChangeEvent(
394      ICreateServiceObjectWithAttachmentParam change) {
395    onChangeList.remove(change);
396  }
397
398  /**
399   * The on change list.
400   */
401  private List<ICreateServiceObjectWithAttachmentParam> onChangeList =
402      new ArrayList<ICreateServiceObjectWithAttachmentParam>();
403
404  /**
405   * The on change list1.
406   */
407  private List<ICreateServiceObjectWithServiceParam> onChangeList1 =
408      new ArrayList<ICreateServiceObjectWithServiceParam>();
409
410  /**
411   * Set event to happen when property changed.
412   *
413   * @param change change event
414   */
415  protected void addOnChangeEvent(
416      ICreateServiceObjectWithServiceParam change) {
417    onChangeList1.add(change);
418  }
419
420  /**
421   * Remove the event from happening when property changed.
422   *
423   * @param change change event
424   */
425  protected void removeChangeEvent(
426      ICreateServiceObjectWithServiceParam change) {
427    onChangeList1.remove(change);
428  }
429
430}