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    
024    package microsoft.exchange.webservices.data.core.service;
025    
026    import microsoft.exchange.webservices.data.core.ExchangeService;
027    import microsoft.exchange.webservices.data.core.XmlElementNames;
028    import microsoft.exchange.webservices.data.core.service.folder.CalendarFolder;
029    import microsoft.exchange.webservices.data.core.service.folder.ContactsFolder;
030    import microsoft.exchange.webservices.data.core.service.folder.Folder;
031    import microsoft.exchange.webservices.data.core.service.folder.SearchFolder;
032    import microsoft.exchange.webservices.data.core.service.folder.TasksFolder;
033    import microsoft.exchange.webservices.data.core.service.item.Appointment;
034    import microsoft.exchange.webservices.data.core.service.item.Contact;
035    import microsoft.exchange.webservices.data.core.service.item.ContactGroup;
036    import microsoft.exchange.webservices.data.core.service.item.Conversation;
037    import microsoft.exchange.webservices.data.core.service.item.EmailMessage;
038    import microsoft.exchange.webservices.data.core.service.item.Item;
039    import microsoft.exchange.webservices.data.core.service.item.MeetingCancellation;
040    import microsoft.exchange.webservices.data.core.service.item.MeetingMessage;
041    import microsoft.exchange.webservices.data.core.service.item.MeetingRequest;
042    import microsoft.exchange.webservices.data.core.service.item.MeetingResponse;
043    import microsoft.exchange.webservices.data.core.service.item.PostItem;
044    import microsoft.exchange.webservices.data.core.service.item.Task;
045    import microsoft.exchange.webservices.data.property.complex.ItemAttachment;
046    
047    import java.util.ArrayList;
048    import java.util.HashMap;
049    import java.util.List;
050    import 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     */
057    public 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    }