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.item;
025    
026    import microsoft.exchange.webservices.data.attribute.Attachable;
027    import microsoft.exchange.webservices.data.attribute.ServiceObjectDefinition;
028    import microsoft.exchange.webservices.data.core.EwsUtilities;
029    import microsoft.exchange.webservices.data.core.ExchangeService;
030    import microsoft.exchange.webservices.data.core.PropertySet;
031    import microsoft.exchange.webservices.data.core.XmlElementNames;
032    import microsoft.exchange.webservices.data.core.service.response.AcceptMeetingInvitationMessage;
033    import microsoft.exchange.webservices.data.core.service.response.CancelMeetingMessage;
034    import microsoft.exchange.webservices.data.core.service.response.DeclineMeetingInvitationMessage;
035    import microsoft.exchange.webservices.data.core.service.response.ResponseMessage;
036    import microsoft.exchange.webservices.data.core.service.schema.AppointmentSchema;
037    import microsoft.exchange.webservices.data.core.service.schema.ServiceObjectSchema;
038    import microsoft.exchange.webservices.data.core.enumeration.service.calendar.AppointmentType;
039    import microsoft.exchange.webservices.data.core.enumeration.service.ConflictResolutionMode;
040    import microsoft.exchange.webservices.data.core.enumeration.service.DeleteMode;
041    import microsoft.exchange.webservices.data.core.enumeration.misc.ExchangeVersion;
042    import microsoft.exchange.webservices.data.core.enumeration.property.LegacyFreeBusyStatus;
043    import microsoft.exchange.webservices.data.core.enumeration.property.MeetingResponseType;
044    import microsoft.exchange.webservices.data.core.enumeration.service.ResponseMessageType;
045    import microsoft.exchange.webservices.data.core.enumeration.service.SendCancellationsMode;
046    import microsoft.exchange.webservices.data.core.enumeration.service.SendInvitationsMode;
047    import microsoft.exchange.webservices.data.core.enumeration.service.SendInvitationsOrCancellationsMode;
048    import microsoft.exchange.webservices.data.core.enumeration.property.WellKnownFolderName;
049    import microsoft.exchange.webservices.data.core.exception.service.local.ServiceLocalException;
050    import microsoft.exchange.webservices.data.misc.CalendarActionResults;
051    import microsoft.exchange.webservices.data.misc.TimeSpan;
052    import microsoft.exchange.webservices.data.property.complex.AppointmentOccurrenceId;
053    import microsoft.exchange.webservices.data.property.complex.AttendeeCollection;
054    import microsoft.exchange.webservices.data.property.complex.DeletedOccurrenceInfoCollection;
055    import microsoft.exchange.webservices.data.property.complex.EmailAddress;
056    import microsoft.exchange.webservices.data.property.complex.FolderId;
057    import microsoft.exchange.webservices.data.property.complex.ItemAttachment;
058    import microsoft.exchange.webservices.data.property.complex.ItemCollection;
059    import microsoft.exchange.webservices.data.property.complex.ItemId;
060    import microsoft.exchange.webservices.data.property.complex.MessageBody;
061    import microsoft.exchange.webservices.data.property.complex.OccurrenceInfo;
062    import microsoft.exchange.webservices.data.property.complex.OccurrenceInfoCollection;
063    import microsoft.exchange.webservices.data.property.complex.RecurringAppointmentMasterId;
064    import microsoft.exchange.webservices.data.property.complex.recurrence.pattern.Recurrence;
065    import microsoft.exchange.webservices.data.property.complex.time.TimeZoneDefinition;
066    
067    import java.util.Arrays;
068    import java.util.Date;
069    
070    /**
071     * Represents an appointment or a meeting. Properties available on appointments
072     * are defined in the AppointmentSchema class.
073     */
074    @Attachable
075    @ServiceObjectDefinition(xmlElementName = XmlElementNames.CalendarItem)
076    public class Appointment extends Item implements ICalendarActionProvider {
077    
078      /**
079       * Initializes an unsaved local instance of Appointment". To bind to an
080       * existing appointment, use Appointment.Bind() instead.
081       *
082       * @param service The ExchangeService instance to which this appointmtnt is
083       *                bound.
084       * @throws Exception the exception
085       */
086      public Appointment(ExchangeService service) throws Exception {
087        super(service);
088      }
089    
090      /**
091       * Initializes a new instance of Appointment.
092       *
093       * @param parentAttachment the parent attachment
094       * @param isNew            If true, attachment is new.
095       * @throws Exception the exception
096       */
097      public Appointment(ItemAttachment parentAttachment, boolean isNew)
098          throws Exception {
099        // If we're running against Exchange 2007, we need to explicitly preset
100        // the StartTimeZone property since Exchange 2007 will otherwise scope
101        // start and end to UTC.
102        super(parentAttachment);
103      }
104    
105      /**
106       * Binds to an existing appointment and loads the specified set of
107       * property. Calling this method results in a call to EWS.
108       *
109       * @param service     the service
110       * @param id          the id
111       * @param propertySet the property set
112       * @return An Appointment instance representing the appointment
113       * corresponding to the specified Id.
114       * @throws Exception the exception
115       */
116      public static Appointment bind(ExchangeService service, ItemId id,
117          PropertySet propertySet) throws Exception {
118        return service.bindToItem(Appointment.class, id, propertySet);
119      }
120    
121      /**
122       * Binds to an existing appointment and loads its first class property.
123       * Calling this method results in a call to EWS.
124       *
125       * @param service the service
126       * @param id      the id
127       * @return An Appointment instance representing the appointment
128       * corresponding to the specified Id.
129       * @throws Exception the exception
130       */
131      public static Appointment bind(ExchangeService service, ItemId id)
132          throws Exception {
133        return Appointment.bind(service, id, PropertySet.FirstClassProperties);
134      }
135    
136      /**
137       * Binds to an existing appointment and loads its first class property.
138       * Calling this method results in a call to EWS.
139       *
140       * @param service           the service
141       * @param recurringMasterId the recurring master id
142       * @param occurenceIndex    the occurence index
143       * @return An Appointment instance representing the appointment
144       * corresponding to the specified Id.
145       * @throws Exception the exception
146       */
147      public static Appointment bindToOccurrence(ExchangeService service,
148          ItemId recurringMasterId, int occurenceIndex) throws Exception {
149        return Appointment.bindToOccurrence(service, recurringMasterId,
150            occurenceIndex, PropertySet.FirstClassProperties);
151      }
152    
153      /**
154       * Binds to an existing appointment and loads its first class property.
155       * Calling this method results in a call to EWS.
156       *
157       * @param service           the service
158       * @param recurringMasterId the recurring master id
159       * @param occurenceIndex    the occurence index
160       * @param propertySet       the property set
161       * @return An Appointment instance representing the appointment
162       * corresponding to the specified Id.
163       * @throws Exception the exception
164       */
165      public static Appointment bindToOccurrence(ExchangeService service,
166          ItemId recurringMasterId, int occurenceIndex,
167          PropertySet propertySet) throws Exception {
168        AppointmentOccurrenceId occurenceId = new AppointmentOccurrenceId(
169            recurringMasterId.getUniqueId(), occurenceIndex);
170        return Appointment.bind(service, occurenceId, propertySet);
171      }
172    
173      /**
174       * Binds to the master appointment of a recurring series and loads its first
175       * class property. Calling this method results in a call to EWS.
176       *
177       * @param service      the service
178       * @param occurrenceId the occurrence id
179       * @return An Appointment instance representing the appointment
180       * corresponding to the specified Id.
181       * @throws Exception the exception
182       */
183      public static Appointment bindToRecurringMaster(ExchangeService service,
184          ItemId occurrenceId) throws Exception {
185        return Appointment.bindToRecurringMaster(service, occurrenceId,
186            PropertySet.FirstClassProperties);
187      }
188    
189      /**
190       * Binds to the master appointment of a recurring series and loads its first
191       * class property. Calling this method results in a call to EWS.
192       *
193       * @param service      the service
194       * @param occurrenceId the occurrence id
195       * @param propertySet  the property set
196       * @return An Appointment instance representing the appointment
197       * corresponding to the specified Id.
198       * @throws Exception the exception
199       */
200      public static Appointment bindToRecurringMaster(ExchangeService service,
201          ItemId occurrenceId, PropertySet propertySet) throws Exception {
202        RecurringAppointmentMasterId recurringMasterId =
203            new RecurringAppointmentMasterId(
204                occurrenceId.getUniqueId());
205        return Appointment.bind(service, recurringMasterId, propertySet);
206      }
207    
208      /**
209       * Internal method to return the schema associated with this type of object.
210       *
211       * @return The schema associated with this type of object
212       */
213      @Override public ServiceObjectSchema getSchema() {
214        return AppointmentSchema.Instance;
215      }
216    
217      /**
218       * Gets the minimum required server version.
219       *
220       * @return Earliest Exchange version in which this service object type is
221       * supported.
222       */
223      @Override public ExchangeVersion getMinimumRequiredServerVersion() {
224        return ExchangeVersion.Exchange2007_SP1;
225      }
226    
227      /**
228       * Determines whether property defined with
229       * ScopedDateTimePropertyDefinition require custom time zone scoping.
230       *
231       * @return if this item type requires custom scoping for scoped date/time
232       * property; otherwise, .
233       */
234      @Override
235      protected boolean getIsCustomDateTimeScopingRequired() {
236        return true;
237      }
238    
239      /**
240       * Validates this instance.
241       *
242       * @throws Exception
243       */
244      @Override public void validate() throws Exception {
245        super.validate();
246    
247        //  PS # 250452: Make sure that if we're
248        //on the Exchange2007_SP1 schema version,
249        // if any of the following
250        //  property are set or updated:
251        //      o   Start
252        //      o   End
253        //      o   IsAllDayEvent
254        //      o   Recurrence
255        //  ... then, we must send the MeetingTimeZone element
256        // (which is generated from StartTimeZone for
257        //  Exchange2007_SP1 request (see
258        //StartTimeZonePropertyDefinition.cs).
259        // If the StartTimeZone isn't
260        //  in the property bag, then throw, because clients must
261        // supply the proper time zone - either by
262        //  loading it from a currently-existing appointment,
263        //or by setting it directly.
264        // Otherwise, to dirty
265        //  the StartTimeZone property, we just set it to its current value.
266        if ((this.getService().getRequestedServerVersion() == ExchangeVersion.Exchange2007_SP1) &&
267            !(this.getService().getExchange2007CompatibilityMode())) {
268          if (this.getPropertyBag().isPropertyUpdated(AppointmentSchema.Start) ||
269              this.getPropertyBag().isPropertyUpdated(AppointmentSchema.End) ||
270              this.getPropertyBag().isPropertyUpdated(AppointmentSchema.IsAllDayEvent) ||
271              this.getPropertyBag().isPropertyUpdated(AppointmentSchema.Recurrence)) {
272            //  If the property isn't in the property bag, throw....
273            if (!this.getPropertyBag().contains(AppointmentSchema.StartTimeZone)) {
274              throw new ServiceLocalException("StartTimeZone required when setting the Start, End, IsAllDayEvent, "
275                                              + "or Recurrence property.  You must load or assign this property "
276                                              + "before attempting to update the appointment.");
277              //getStartTimeZoneRequired());
278            }
279    
280            //  Otherwise, set the time zone to its current value to
281            // force it to be sent with the request.
282            this.setStartTimeZone(this.getStartTimeZone());
283          }
284        }
285      }
286    
287      /**
288       * Creates a reply response to the organizer and/or attendees of the
289       * meeting.
290       *
291       * @param replyAll the reply all
292       * @return A ResponseMessage representing the reply response that can
293       * subsequently be modified and sent.
294       * @throws Exception the exception
295       */
296      public ResponseMessage createReply(boolean replyAll) throws Exception {
297        this.throwIfThisIsNew();
298    
299        return new ResponseMessage(this,
300            replyAll ? ResponseMessageType.ReplyAll :
301                ResponseMessageType.Reply);
302      }
303    
304      /**
305       * Replies to the organizer and/or the attendees of the meeting. Calling
306       * this method results in a call to EWS.
307       *
308       * @param bodyPrefix the body prefix
309       * @param replyAll   the reply all
310       * @throws Exception the exception
311       */
312      public void reply(MessageBody bodyPrefix, boolean replyAll)
313          throws Exception {
314        ResponseMessage responseMessage = this.createReply(replyAll);
315    
316        responseMessage.setBodyPrefix(bodyPrefix);
317        responseMessage.sendAndSaveCopy();
318      }
319    
320      /**
321       * Creates a forward message from this appointment.
322       *
323       * @return A ResponseMessage representing the forward response that can
324       * subsequently be modified and sent.
325       * @throws Exception the exception
326       */
327      public ResponseMessage createForward() throws Exception {
328        this.throwIfThisIsNew();
329        return new ResponseMessage(this, ResponseMessageType.Forward);
330      }
331    
332      /**
333       * Forwards the appointment. Calling this method results in a call to EWS.
334       *
335       * @param bodyPrefix   the body prefix
336       * @param toRecipients the to recipients
337       * @throws Exception the exception
338       */
339      public void forward(MessageBody bodyPrefix, EmailAddress... toRecipients)
340          throws Exception {
341        if (null != toRecipients) {
342          forward(bodyPrefix, Arrays.asList(toRecipients));
343        }
344      }
345    
346      /**
347       * Forwards the appointment. Calling this method results in a call to EWS.
348       *
349       * @param bodyPrefix   the body prefix
350       * @param toRecipients the to recipients
351       * @throws Exception the exception
352       */
353      public void forward(MessageBody bodyPrefix,
354          Iterable<EmailAddress> toRecipients) throws Exception {
355        ResponseMessage responseMessage = this.createForward();
356    
357        responseMessage.setBodyPrefix(bodyPrefix);
358        responseMessage.getToRecipients()
359            .addEmailRange(toRecipients.iterator());
360    
361        responseMessage.sendAndSaveCopy();
362      }
363    
364      /**
365       * Saves this appointment in the specified folder. Calling this method
366       * results in at least one call to EWS. Mutliple calls to EWS might be made
367       * if attachments have been added.
368       *
369       * @param destinationFolderName the destination folder name
370       * @param sendInvitationsMode   the send invitations mode
371       * @throws Exception the exception
372       */
373      public void save(WellKnownFolderName destinationFolderName,
374          SendInvitationsMode sendInvitationsMode) throws Exception {
375        this.internalCreate(new FolderId(destinationFolderName), null,
376            sendInvitationsMode);
377      }
378    
379      /**
380       * Saves this appointment in the specified folder. Calling this method
381       * results in at least one call to EWS. Mutliple calls to EWS might be made
382       * if attachments have been added.
383       *
384       * @param destinationFolderId the destination folder id
385       * @param sendInvitationsMode the send invitations mode
386       * @throws Exception the exception
387       */
388      public void save(FolderId destinationFolderId,
389          SendInvitationsMode sendInvitationsMode) throws Exception {
390        EwsUtilities.validateParam(destinationFolderId, "destinationFolderId");
391    
392        this.internalCreate(destinationFolderId, null, sendInvitationsMode);
393      }
394    
395      /**
396       * Saves this appointment in the Calendar folder. Calling this method
397       * results in at least one call to EWS. Mutliple calls to EWS might be made
398       * if attachments have been added.
399       *
400       * @param sendInvitationsMode the send invitations mode
401       * @throws Exception the exception
402       */
403      public void save(SendInvitationsMode sendInvitationsMode) throws Exception {
404        this.internalCreate(null, null, sendInvitationsMode);
405      }
406    
407      /**
408       * Applies the local changes that have been made to this appointment.
409       * Calling this method results in at least one call to EWS. Mutliple calls
410       * to EWS might be made if attachments have been added or removed.
411       *
412       * @param conflictResolutionMode             the conflict resolution mode
413       * @param sendInvitationsOrCancellationsMode the send invitations or cancellations mode
414       * @throws Exception the exception
415       */
416      public void update(
417          ConflictResolutionMode conflictResolutionMode,
418          SendInvitationsOrCancellationsMode
419              sendInvitationsOrCancellationsMode)
420          throws Exception {
421        this.internalUpdate(null, conflictResolutionMode, null,
422            sendInvitationsOrCancellationsMode);
423      }
424    
425      /**
426       * Deletes this appointment. Calling this method results in a call to EWS.
427       *
428       * @param deleteMode            the delete mode
429       * @param sendCancellationsMode the send cancellations mode
430       * @throws Exception the exception
431       */
432      public void delete(DeleteMode deleteMode,
433          SendCancellationsMode sendCancellationsMode) throws Exception {
434        this.internalDelete(deleteMode, sendCancellationsMode, null);
435      }
436    
437      /**
438       * Creates a local meeting acceptance message that can be customized and
439       * sent.
440       *
441       * @param tentative the tentative
442       * @return An AcceptMeetingInvitationMessage representing the meeting
443       * acceptance message.
444       * @throws Exception the exception
445       */
446      public AcceptMeetingInvitationMessage createAcceptMessage(boolean tentative)
447          throws Exception {
448        return new AcceptMeetingInvitationMessage(this, tentative);
449      }
450    
451      /**
452       * Creates a local meeting acceptance message that can be customized and
453       * sent.
454       *
455       * @return A CancelMeetingMessage representing the meeting cancellation
456       * message.
457       * @throws Exception the exception
458       */
459      public CancelMeetingMessage createCancelMeetingMessage() throws Exception {
460        return new CancelMeetingMessage(this);
461      }
462    
463      /**
464       * Creates a local meeting declination message that can be customized and
465       * sent.
466       *
467       * @return A DeclineMeetingInvitation representing the meeting declination
468       * message.
469       * @throws Exception the exception
470       */
471      public DeclineMeetingInvitationMessage createDeclineMessage()
472          throws Exception {
473        return new DeclineMeetingInvitationMessage(this);
474      }
475    
476      /**
477       * Accepts the meeting. Calling this method results in a call to EWS.
478       *
479       * @param sendResponse the send response
480       * @return A CalendarActionResults object containing the various item that
481       * were created or modified as a results of this operation.
482       * @throws Exception the exception
483       */
484      public CalendarActionResults accept(boolean sendResponse) throws Exception {
485        return this.internalAccept(false, sendResponse);
486      }
487    
488      /**
489       * Tentatively accepts the meeting. Calling this method results in a call to
490       * EWS.
491       *
492       * @param sendResponse the send response
493       * @return A CalendarActionResults object containing the various item that
494       * were created or modified as a results of this operation.
495       * @throws Exception the exception
496       */
497      public CalendarActionResults acceptTentatively(boolean sendResponse)
498          throws Exception {
499        return this.internalAccept(true, sendResponse);
500      }
501    
502      /**
503       * Accepts the meeting.
504       *
505       * @param tentative    the tentative
506       * @param sendResponse the send response
507       * @return A CalendarActionResults object containing the various item that
508       * were created or modified as a results of this operation.
509       * @throws Exception the exception
510       */
511      protected CalendarActionResults internalAccept(boolean tentative,
512          boolean sendResponse) throws Exception {
513        AcceptMeetingInvitationMessage accept = this
514            .createAcceptMessage(tentative);
515    
516        if (sendResponse) {
517          return accept.calendarSendAndSaveCopy();
518        } else {
519          return accept.calendarSave();
520        }
521      }
522    
523      /**
524       * Cancels the meeting and sends cancellation messages to all attendees.
525       * Calling this method results in a call to EWS.
526       *
527       * @return A CalendarActionResults object containing the various item that
528       * were created or modified as a results of this operation.
529       * @throws Exception the exception
530       */
531      public CalendarActionResults cancelMeeting() throws Exception {
532        return this.createCancelMeetingMessage().calendarSendAndSaveCopy();
533      }
534    
535      /**
536       * Cancels the meeting and sends cancellation messages to all attendees.
537       * Calling this method results in a call to EWS.
538       *
539       * @param cancellationMessageText the cancellation message text
540       * @return A CalendarActionResults object containing the various item that
541       * were created or modified as a results of this operation.
542       * @throws Exception the exception
543       */
544      public CalendarActionResults cancelMeeting(String cancellationMessageText)
545          throws Exception {
546        CancelMeetingMessage cancelMsg = this.createCancelMeetingMessage();
547        cancelMsg.setBody(new MessageBody(cancellationMessageText));
548        return cancelMsg.calendarSendAndSaveCopy();
549      }
550    
551      /**
552       * Declines the meeting invitation. Calling this method results in a call to
553       * EWS.
554       *
555       * @param sendResponse the send response
556       * @return A CalendarActionResults object containing the various item that
557       * were created or modified as a results of this operation.
558       * @throws Exception the exception
559       */
560      public CalendarActionResults decline(boolean
561          sendResponse) throws Exception {
562        DeclineMeetingInvitationMessage decline = this.createDeclineMessage();
563    
564        if (sendResponse) {
565          return decline.calendarSendAndSaveCopy();
566        } else {
567          return decline.calendarSave();
568        }
569      }
570    
571      /**
572       * Gets the default setting for sending cancellations on Delete.
573       *
574       * @return If Delete() is called on Appointment, we want to send
575       * cancellations and save a copy.
576       */
577      @Override
578      protected SendCancellationsMode getDefaultSendCancellationsMode() {
579        return SendCancellationsMode.SendToAllAndSaveCopy;
580      }
581    
582      /**
583       * Gets the default settings for sending invitations on Save.
584       *
585       * @return the default send invitations mode
586       */
587      @Override
588      protected SendInvitationsMode getDefaultSendInvitationsMode() {
589        return SendInvitationsMode.SendToAllAndSaveCopy;
590      }
591    
592      /**
593       * Gets the default settings for sending invitations on Save.
594       *
595       * @return the default send invitations or cancellations mode
596       */
597      @Override
598      protected SendInvitationsOrCancellationsMode
599      getDefaultSendInvitationsOrCancellationsMode() {
600        return SendInvitationsOrCancellationsMode.SendToAllAndSaveCopy;
601      }
602    
603      // Properties
604    
605      /**
606       * Gets the start time of the appointment.
607       *
608       * @return the start
609       * @throws ServiceLocalException the service local exception
610       */
611      public Date getStart() throws ServiceLocalException {
612        return getPropertyBag().getObjectFromPropertyDefinition(
613            AppointmentSchema.Start);
614      }
615    
616      /**
617       * Sets the start.
618       *
619       * @param value the new start
620       * @throws Exception the exception
621       */
622      public void setStart(Date value) throws Exception {
623        this.getPropertyBag().setObjectFromPropertyDefinition(
624            AppointmentSchema.Start, value);
625      }
626    
627      /**
628       * Gets or sets the end time of the appointment.
629       *
630       * @return the end
631       * @throws ServiceLocalException the service local exception
632       */
633      public Date getEnd() throws ServiceLocalException {
634        return getPropertyBag().getObjectFromPropertyDefinition(
635            AppointmentSchema.End);
636      }
637    
638      /**
639       * Sets the end.
640       *
641       * @param value the new end
642       * @throws Exception the exception
643       */
644      public void setEnd(Date value) throws Exception {
645        this.getPropertyBag().setObjectFromPropertyDefinition(
646            AppointmentSchema.End, value);
647      }
648    
649      /**
650       * Gets the original start time of this appointment.
651       *
652       * @return the original start
653       * @throws ServiceLocalException the service local exception
654       */
655      public Date getOriginalStart() throws ServiceLocalException {
656        return getPropertyBag().getObjectFromPropertyDefinition(
657            AppointmentSchema.OriginalStart);
658      }
659    
660      /**
661       * Gets a value indicating whether this appointment is an all day
662       * event.
663       *
664       * @return the checks if is all day event
665       * @throws ServiceLocalException the service local exception
666       */
667      public Boolean getIsAllDayEvent() throws ServiceLocalException {
668        return getPropertyBag().getObjectFromPropertyDefinition(
669            AppointmentSchema.IsAllDayEvent);
670      }
671    
672      /**
673       * Sets the checks if is all day event.
674       *
675       * @param value the new checks if is all day event
676       * @throws Exception the exception
677       */
678      public void setIsAllDayEvent(Boolean value) throws Exception {
679        this.getPropertyBag().setObjectFromPropertyDefinition(
680            AppointmentSchema.IsAllDayEvent, value);
681      }
682    
683      /**
684       * Gets  a value indicating the free/busy status of the owner of this
685       * appointment.
686       *
687       * @return the legacy free busy status
688       * @throws ServiceLocalException the service local exception
689       */
690      public LegacyFreeBusyStatus getLegacyFreeBusyStatus()
691          throws ServiceLocalException {
692        return getPropertyBag().getObjectFromPropertyDefinition(
693            AppointmentSchema.LegacyFreeBusyStatus);
694      }
695    
696      /**
697       * Sets the legacy free busy status.
698       *
699       * @param value the new legacy free busy status
700       * @throws Exception the exception
701       */
702      public void setLegacyFreeBusyStatus(LegacyFreeBusyStatus value)
703          throws Exception {
704        this.getPropertyBag().setObjectFromPropertyDefinition(
705            AppointmentSchema.LegacyFreeBusyStatus, value);
706      }
707    
708      /**
709       * Gets  the location of this appointment.
710       *
711       * @return the location
712       * @throws ServiceLocalException the service local exception
713       */
714      public String getLocation() throws ServiceLocalException {
715        return getPropertyBag().getObjectFromPropertyDefinition(
716            AppointmentSchema.Location);
717      }
718    
719      /**
720       * Sets the location.
721       *
722       * @param value the new location
723       * @throws Exception the exception
724       */
725      public void setLocation(String value) throws Exception {
726        this.getPropertyBag().setObjectFromPropertyDefinition(
727            AppointmentSchema.Location, value);
728      }
729    
730      /**
731       * Gets a text indicating when this appointment occurs. The text returned by
732       * When is localized using the Exchange Server culture or using the culture
733       * specified in the PreferredCulture property of the ExchangeService object
734       * this appointment is bound to.
735       *
736       * @return the when
737       * @throws ServiceLocalException the service local exception
738       */
739      public String getWhen() throws ServiceLocalException {
740        return getPropertyBag().getObjectFromPropertyDefinition(
741            AppointmentSchema.When);
742      }
743    
744      /**
745       * Gets a value indicating whether the appointment is a meeting.
746       *
747       * @return the checks if is meeting
748       * @throws ServiceLocalException the service local exception
749       */
750      public Boolean getIsMeeting() throws ServiceLocalException {
751        return getPropertyBag().getObjectFromPropertyDefinition(
752            AppointmentSchema.IsMeeting);
753      }
754    
755      /**
756       * Gets a value indicating whether the appointment has been cancelled.
757       *
758       * @return the checks if is cancelled
759       * @throws ServiceLocalException the service local exception
760       */
761      public Boolean getIsCancelled() throws ServiceLocalException {
762        return getPropertyBag().getObjectFromPropertyDefinition(
763            AppointmentSchema.IsCancelled);
764      }
765    
766      /**
767       * Gets a value indicating whether the appointment is recurring.
768       *
769       * @return the checks if is recurring
770       * @throws ServiceLocalException the service local exception
771       */
772      public Boolean getIsRecurring() throws ServiceLocalException {
773        return getPropertyBag().getObjectFromPropertyDefinition(
774            AppointmentSchema.IsRecurring);
775      }
776    
777      /**
778       * Gets a value indicating whether the meeting request has already been
779       * sent.
780       *
781       * @return the meeting request was sent
782       * @throws ServiceLocalException the service local exception
783       */
784      public Boolean getMeetingRequestWasSent() throws ServiceLocalException {
785        return getPropertyBag().getObjectFromPropertyDefinition(
786            AppointmentSchema.MeetingRequestWasSent);
787      }
788    
789      /**
790       * Gets  a value indicating whether response are requested when
791       * invitations are sent for this meeting.
792       *
793       * @return the checks if is response requested
794       * @throws ServiceLocalException the service local exception
795       */
796      public Boolean getIsResponseRequested() throws ServiceLocalException {
797        return getPropertyBag().getObjectFromPropertyDefinition(
798            AppointmentSchema.IsResponseRequested);
799      }
800    
801      /**
802       * Sets the checks if is response requested.
803       *
804       * @param value the new checks if is response requested
805       * @throws Exception the exception
806       */
807      public void setIsResponseRequested(Boolean value) throws Exception {
808        this.getPropertyBag().setObjectFromPropertyDefinition(
809            AppointmentSchema.IsResponseRequested, value);
810      }
811    
812      /**
813       * Gets a value indicating the type of this appointment.
814       *
815       * @return the appointment type
816       * @throws ServiceLocalException the service local exception
817       */
818      public AppointmentType getAppointmentType() throws ServiceLocalException {
819        return getPropertyBag().getObjectFromPropertyDefinition(
820            AppointmentSchema.AppointmentType);
821      }
822    
823      /**
824       * Gets a value indicating what was the last response of the user that
825       * loaded this meeting.
826       *
827       * @return the my response type
828       * @throws ServiceLocalException the service local exception
829       */
830      public MeetingResponseType getMyResponseType()
831          throws ServiceLocalException {
832        return getPropertyBag().getObjectFromPropertyDefinition(
833            AppointmentSchema.MyResponseType);
834      }
835    
836      /**
837       * Gets the organizer of this meeting. The Organizer property is read-only
838       * and is only relevant for attendees. The organizer of a meeting is
839       * automatically set to the user that created the meeting.
840       *
841       * @return the organizer
842       * @throws ServiceLocalException the service local exception
843       */
844      public EmailAddress getOrganizer() throws ServiceLocalException {
845        return getPropertyBag().getObjectFromPropertyDefinition(
846            AppointmentSchema.Organizer);
847      }
848    
849      /**
850       * Gets a list of required attendees for this meeting.
851       *
852       * @return the required attendees
853       * @throws ServiceLocalException the service local exception
854       */
855      public AttendeeCollection getRequiredAttendees()
856          throws ServiceLocalException {
857        return getPropertyBag().getObjectFromPropertyDefinition(
858            AppointmentSchema.RequiredAttendees);
859      }
860    
861      /**
862       * Gets a list of optional attendeed for this meeting.
863       *
864       * @return the optional attendees
865       * @throws ServiceLocalException the service local exception
866       */
867      public AttendeeCollection getOptionalAttendees()
868          throws ServiceLocalException {
869        return getPropertyBag().getObjectFromPropertyDefinition(
870            AppointmentSchema.OptionalAttendees);
871      }
872    
873      /**
874       * Gets a list of resources for this meeting.
875       *
876       * @return the resources
877       * @throws ServiceLocalException the service local exception
878       */
879      public AttendeeCollection getResources() throws ServiceLocalException {
880        return getPropertyBag().getObjectFromPropertyDefinition(
881            AppointmentSchema.Resources);
882      }
883    
884      /**
885       * Gets the number of calendar entries that conflict with this appointment
886       * in the authenticated user's calendar.
887       *
888       * @return the conflicting meeting count
889       * @throws ServiceLocalException the service local exception
890       */
891      public Integer getConflictingMeetingCount() throws ServiceLocalException {
892        return getPropertyBag().getObjectFromPropertyDefinition(
893            AppointmentSchema.ConflictingMeetingCount);
894      }
895    
896      /**
897       * Gets the number of calendar entries that are adjacent to this appointment
898       * in the authenticated user's calendar.
899       *
900       * @return the adjacent meeting count
901       * @throws ServiceLocalException the service local exception
902       */
903      public Integer getAdjacentMeetingCount() throws ServiceLocalException {
904        return getPropertyBag().getObjectFromPropertyDefinition(
905            AppointmentSchema.AdjacentMeetingCount);
906      }
907    
908      /**
909       * Gets a list of meetings that conflict with this appointment in the
910       * authenticated user's calendar.
911       *
912       * @return the conflicting meetings
913       * @throws ServiceLocalException the service local exception
914       */
915      public ItemCollection<Appointment> getConflictingMeetings()
916          throws ServiceLocalException {
917        return getPropertyBag().getObjectFromPropertyDefinition(
918            AppointmentSchema.ConflictingMeetings);
919      }
920    
921      /**
922       * Gets a list of meetings that conflict with this appointment in the
923       * authenticated user's calendar.
924       *
925       * @return the adjacent meetings
926       * @throws ServiceLocalException the service local exception
927       */
928      public ItemCollection<Appointment> getAdjacentMeetings()
929          throws ServiceLocalException {
930        return getPropertyBag().getObjectFromPropertyDefinition(
931                AppointmentSchema.AdjacentMeetings);
932      }
933    
934      /**
935       * Gets the duration of this appointment.
936       *
937       * @return the duration
938       * @throws ServiceLocalException the service local exception
939       */
940      public TimeSpan getDuration() throws ServiceLocalException {
941        return getPropertyBag().getObjectFromPropertyDefinition(
942            AppointmentSchema.Duration);
943      }
944    
945      /**
946       * Gets the name of the time zone this appointment is defined in.
947       *
948       * @return the time zone
949       * @throws ServiceLocalException the service local exception
950       */
951      public String getTimeZone() throws ServiceLocalException {
952        return getPropertyBag().getObjectFromPropertyDefinition(
953            AppointmentSchema.TimeZone);
954      }
955    
956      /**
957       * Gets the time when the attendee replied to the meeting request.
958       *
959       * @return the appointment reply time
960       * @throws ServiceLocalException the service local exception
961       */
962      public Date getAppointmentReplyTime() throws ServiceLocalException {
963        return getPropertyBag().getObjectFromPropertyDefinition(
964            AppointmentSchema.AppointmentReplyTime);
965      }
966    
967      /**
968       * Gets the sequence number of this appointment.
969       *
970       * @return the appointment sequence number
971       * @throws ServiceLocalException the service local exception
972       */
973      public Integer getAppointmentSequenceNumber() throws ServiceLocalException {
974        return getPropertyBag().getObjectFromPropertyDefinition(
975            AppointmentSchema.AppointmentSequenceNumber);
976      }
977    
978      /**
979       * Gets the state of this appointment.
980       *
981       * @return the appointment state
982       * @throws ServiceLocalException the service local exception
983       */
984      public Integer getAppointmentState() throws ServiceLocalException {
985        return getPropertyBag().getObjectFromPropertyDefinition(
986            AppointmentSchema.AppointmentState);
987      }
988    
989      /**
990       * Gets the recurrence pattern for this appointment. Available
991       * recurrence pattern classes include Recurrence.DailyPattern,
992       * Recurrence.MonthlyPattern and Recurrence.YearlyPattern.
993       *
994       * @return the recurrence
995       * @throws ServiceLocalException the service local exception
996       */
997      public Recurrence getRecurrence() throws ServiceLocalException {
998        return getPropertyBag().getObjectFromPropertyDefinition(
999            AppointmentSchema.Recurrence);
1000      }
1001    
1002      /**
1003       * Sets the recurrence.
1004       *
1005       * @param value the new recurrence
1006       * @throws Exception the exception
1007       */
1008      public void setRecurrence(Recurrence value) throws Exception {
1009        if (value != null) {
1010          if (value.isRegenerationPattern()) {
1011            throw new ServiceLocalException("Regeneration pattern can only be used with Task item.");
1012          }
1013        }
1014        this.getPropertyBag().setObjectFromPropertyDefinition(
1015            AppointmentSchema.Recurrence, value);
1016      }
1017    
1018      /**
1019       * Gets an OccurrenceInfo identifying the first occurrence of this meeting.
1020       *
1021       * @return the first occurrence
1022       * @throws ServiceLocalException the service local exception
1023       */
1024      public OccurrenceInfo getFirstOccurrence() throws ServiceLocalException {
1025        return getPropertyBag().getObjectFromPropertyDefinition(
1026              AppointmentSchema.FirstOccurrence);
1027      }
1028    
1029      /**
1030       * Gets an OccurrenceInfo identifying the first occurrence of this meeting.
1031       *
1032       * @return the last occurrence
1033       * @throws ServiceLocalException the service local exception
1034       */
1035      public OccurrenceInfo getLastOccurrence() throws ServiceLocalException {
1036        return getPropertyBag().getObjectFromPropertyDefinition(
1037              AppointmentSchema.LastOccurrence);
1038      }
1039    
1040      /**
1041       * Gets a list of modified occurrences for this meeting.
1042       *
1043       * @return the modified occurrences
1044       * @throws ServiceLocalException the service local exception
1045       */
1046      public OccurrenceInfoCollection getModifiedOccurrences()
1047          throws ServiceLocalException {
1048        return getPropertyBag().getObjectFromPropertyDefinition(
1049              AppointmentSchema.ModifiedOccurrences);
1050      }
1051    
1052      /**
1053       * Gets a list of deleted occurrences for this meeting.
1054       *
1055       * @return the deleted occurrences
1056       * @throws ServiceLocalException the service local exception
1057       */
1058      public DeletedOccurrenceInfoCollection getDeletedOccurrences()
1059          throws ServiceLocalException {
1060        return getPropertyBag().getObjectFromPropertyDefinition(
1061              AppointmentSchema.DeletedOccurrences);
1062      }
1063    
1064      /**
1065       * Gets the start time zone.
1066       *
1067       * @return the start time zone
1068       * @throws ServiceLocalException the service local exception
1069       */
1070      public TimeZoneDefinition getStartTimeZone() throws ServiceLocalException {
1071        return getPropertyBag().getObjectFromPropertyDefinition(
1072              AppointmentSchema.StartTimeZone);
1073      }
1074    
1075      /**
1076       * Sets the start time zone.
1077       *
1078       * @param value the new start time zone
1079       * @throws Exception the exception
1080       */
1081      public void setStartTimeZone(TimeZoneDefinition value) throws Exception {
1082        this.getPropertyBag().setObjectFromPropertyDefinition(
1083            AppointmentSchema.StartTimeZone, value);
1084    
1085      }
1086    
1087      /**
1088       * Gets the start time zone.
1089       *
1090       * @return the start time zone
1091       * @throws ServiceLocalException the service local exception
1092       */
1093      public TimeZoneDefinition getEndTimeZone() throws ServiceLocalException {
1094        return getPropertyBag()
1095            .getObjectFromPropertyDefinition(AppointmentSchema.EndTimeZone);
1096      }
1097    
1098      /**
1099       * Sets the start time zone.
1100       *
1101       * @param value the new end time zone
1102       * @throws Exception the exception
1103       */
1104      public void setEndTimeZone(TimeZoneDefinition value) throws Exception {
1105        this.getPropertyBag().setObjectFromPropertyDefinition(
1106            AppointmentSchema.EndTimeZone, value);
1107    
1108      }
1109    
1110      /**
1111       * Gets  the type of conferencing that will be used during the
1112       * meeting.
1113       *
1114       * @return the conference type
1115       * @throws ServiceLocalException the service local exception
1116       */
1117      public Integer getConferenceType() throws ServiceLocalException {
1118        return getPropertyBag().getObjectFromPropertyDefinition(
1119            AppointmentSchema.ConferenceType);
1120      }
1121    
1122      /**
1123       * Sets the conference type.
1124       *
1125       * @param value the new conference type
1126       * @throws Exception the exception
1127       */
1128      public void setConferenceType(Integer value) throws Exception {
1129        this.getPropertyBag().setObjectFromPropertyDefinition(
1130            AppointmentSchema.ConferenceType, value);
1131      }
1132    
1133      /**
1134       * Gets a value indicating whether new time proposals are allowed
1135       * for attendees of this meeting.
1136       *
1137       * @return the allow new time proposal
1138       * @throws ServiceLocalException the service local exception
1139       */
1140      public Boolean getAllowNewTimeProposal() throws ServiceLocalException {
1141        return getPropertyBag().getObjectFromPropertyDefinition(
1142            AppointmentSchema.AllowNewTimeProposal);
1143      }
1144    
1145      /**
1146       * Sets the allow new time proposal.
1147       *
1148       * @param value the new allow new time proposal
1149       * @throws Exception the exception
1150       */
1151      public void setAllowNewTimeProposal(Boolean value) throws Exception {
1152        this.getPropertyBag().setObjectFromPropertyDefinition(
1153            AppointmentSchema.AllowNewTimeProposal, value);
1154      }
1155    
1156      /**
1157       * Gets  a value indicating whether this is an online meeting.
1158       *
1159       * @return the checks if is online meeting
1160       * @throws ServiceLocalException the service local exception
1161       */
1162      public Boolean getIsOnlineMeeting() throws ServiceLocalException {
1163        return getPropertyBag().getObjectFromPropertyDefinition(
1164            AppointmentSchema.IsOnlineMeeting);
1165      }
1166    
1167      /**
1168       * Sets the checks if is online meeting.
1169       *
1170       * @param value the new checks if is online meeting
1171       * @throws Exception the exception
1172       */
1173      public void setIsOnlineMeeting(Boolean value) throws Exception {
1174        this.getPropertyBag().setObjectFromPropertyDefinition(
1175            AppointmentSchema.IsOnlineMeeting, value);
1176      }
1177    
1178      /**
1179       * Gets  the URL of the meeting workspace. A meeting workspace is a
1180       * shared Web site for planning meetings and tracking results.
1181       *
1182       * @return the meeting workspace url
1183       * @throws ServiceLocalException the service local exception
1184       */
1185      public String getMeetingWorkspaceUrl() throws ServiceLocalException {
1186        return getPropertyBag().getObjectFromPropertyDefinition(
1187            AppointmentSchema.MeetingWorkspaceUrl);
1188      }
1189    
1190      /**
1191       * Sets the meeting workspace url.
1192       *
1193       * @param value the new meeting workspace url
1194       * @throws Exception the exception
1195       */
1196      public void setMeetingWorkspaceUrl(String value) throws Exception {
1197        this.getPropertyBag().setObjectFromPropertyDefinition(
1198            AppointmentSchema.MeetingWorkspaceUrl, value);
1199      }
1200    
1201      /**
1202       * Gets the URL of the Microsoft NetShow online meeting.
1203       *
1204       * @return the net show url
1205       * @throws ServiceLocalException the service local exception
1206       */
1207      public String getNetShowUrl() throws ServiceLocalException {
1208        return getPropertyBag().getObjectFromPropertyDefinition(
1209            AppointmentSchema.NetShowUrl);
1210      }
1211    
1212      /**
1213       * Sets the net show url.
1214       *
1215       * @param value the new net show url
1216       * @throws Exception the exception
1217       */
1218      public void setNetShowUrl(String value) throws Exception {
1219        this.getPropertyBag().setObjectFromPropertyDefinition(
1220            AppointmentSchema.NetShowUrl, value);
1221      }
1222    
1223      /**
1224       * Gets the ICalendar Uid.
1225       *
1226       * @return the i cal uid
1227       * @throws ServiceLocalException the service local exception
1228       */
1229      public String getICalUid() throws ServiceLocalException {
1230        return getPropertyBag().getObjectFromPropertyDefinition(
1231            AppointmentSchema.ICalUid);
1232      }
1233    
1234      /**
1235       * Sets the ICalendar Uid.
1236       *
1237       * @param value the i cal uid
1238       * @throws Exception
1239       *///this.PropertyBag[AppointmentSchema.ICalUid] = value;
1240      public void setICalUid(String value) throws Exception {
1241        this.getPropertyBag().setObjectFromPropertyDefinition(
1242            AppointmentSchema.ICalUid, value);
1243      }
1244    
1245      /**
1246       * Gets the ICalendar RecurrenceId.
1247       *
1248       * @return the i cal recurrence id
1249       * @throws ServiceLocalException the service local exception
1250       */
1251      public Date getICalRecurrenceId() throws ServiceLocalException {
1252        return getPropertyBag().getObjectFromPropertyDefinition(
1253            AppointmentSchema.ICalRecurrenceId);
1254      }
1255    
1256      /**
1257       * Gets the ICalendar DateTimeStamp.
1258       *
1259       * @return the i cal date time stamp
1260       * @throws ServiceLocalException the service local exception
1261       */
1262      public Date getICalDateTimeStamp() throws ServiceLocalException {
1263        return getPropertyBag().getObjectFromPropertyDefinition(
1264            AppointmentSchema.ICalDateTimeStamp);
1265      }
1266    }