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.property.complex.recurrence.pattern;
025
026 import microsoft.exchange.webservices.data.attribute.EditorBrowsable;
027 import microsoft.exchange.webservices.data.core.EwsServiceXmlReader;
028 import microsoft.exchange.webservices.data.core.EwsServiceXmlWriter;
029 import microsoft.exchange.webservices.data.core.EwsUtilities;
030 import microsoft.exchange.webservices.data.core.ExchangeService;
031 import microsoft.exchange.webservices.data.core.XmlElementNames;
032 import microsoft.exchange.webservices.data.core.enumeration.property.time.DayOfTheWeek;
033 import microsoft.exchange.webservices.data.core.enumeration.property.time.DayOfTheWeekIndex;
034 import microsoft.exchange.webservices.data.core.enumeration.attribute.EditorBrowsableState;
035 import microsoft.exchange.webservices.data.core.enumeration.misc.ExchangeVersion;
036 import microsoft.exchange.webservices.data.core.enumeration.property.time.Month;
037 import microsoft.exchange.webservices.data.core.enumeration.misc.XmlNamespace;
038 import microsoft.exchange.webservices.data.core.exception.misc.ArgumentException;
039 import microsoft.exchange.webservices.data.core.exception.misc.ArgumentOutOfRangeException;
040 import microsoft.exchange.webservices.data.core.exception.service.local.ServiceValidationException;
041 import microsoft.exchange.webservices.data.property.complex.ComplexProperty;
042 import microsoft.exchange.webservices.data.property.complex.IComplexPropertyChangedDelegate;
043 import microsoft.exchange.webservices.data.property.complex.recurrence.DayOfTheWeekCollection;
044 import microsoft.exchange.webservices.data.property.complex.recurrence.range.EndDateRecurrenceRange;
045 import microsoft.exchange.webservices.data.property.complex.recurrence.range.NoEndRecurrenceRange;
046 import microsoft.exchange.webservices.data.property.complex.recurrence.range.NumberedRecurrenceRange;
047 import microsoft.exchange.webservices.data.property.complex.recurrence.range.RecurrenceRange;
048
049 import java.util.ArrayList;
050 import java.util.Arrays;
051 import java.util.Calendar;
052 import java.util.Date;
053 import java.util.Iterator;
054
055 /**
056 * Represents a recurrence pattern, as used by Appointment and Task item.
057 */
058 public abstract class Recurrence extends ComplexProperty {
059
060 /**
061 * The start date.
062 */
063 private Date startDate;
064
065 /**
066 * The number of occurrences.
067 */
068 private Integer numberOfOccurrences;
069
070 /**
071 * The end date.
072 */
073 private Date endDate;
074
075 /**
076 * Initializes a new instance.
077 */
078 public Recurrence() {
079 super();
080 }
081
082 /**
083 * Initializes a new instance.
084 *
085 * @param startDate the start date
086 */
087 public Recurrence(Date startDate) {
088 this();
089 this.startDate = startDate;
090 }
091
092 /**
093 * Gets the name of the XML element.
094 *
095 * @return the xml element name
096 */
097 public abstract String getXmlElementName();
098
099 /**
100 * Gets a value indicating whether this instance is regeneration pattern.
101 *
102 * @return true, if is regeneration pattern
103 */
104 public boolean isRegenerationPattern() {
105 return false;
106 }
107
108 /**
109 * Write property to XML.
110 *
111 * @param writer the writer
112 * @throws Exception the exception
113 */
114 public void internalWritePropertiesToXml(EwsServiceXmlWriter writer) throws Exception {
115 }
116
117 /**
118 * Writes elements to XML.
119 *
120 * @param writer the writer
121 * @throws Exception the exception
122 */
123 @Override
124 public final void writeElementsToXml(EwsServiceXmlWriter writer)
125 throws Exception {
126 writer.writeStartElement(XmlNamespace.Types, this.getXmlElementName());
127 this.internalWritePropertiesToXml(writer);
128 writer.writeEndElement();
129
130 RecurrenceRange range = null;
131
132 if (!this.hasEnd()) {
133 range = new NoEndRecurrenceRange(this.getStartDate());
134 } else if (this.getNumberOfOccurrences() != null) {
135 range = new NumberedRecurrenceRange(this.startDate,
136 this.numberOfOccurrences);
137 } else {
138 if (this.getEndDate() != null) {
139 range = new EndDateRecurrenceRange(this.getStartDate(), this
140 .getEndDate());
141 }
142 }
143 if (range != null) {
144 range.writeToXml(writer, range.getXmlElementName());
145 }
146
147 }
148
149 /**
150 * Gets a property value or throw if null. *
151 *
152 * @param <T> the generic type
153 * @param cls the cls
154 * @param value the value
155 * @param name the name
156 * @return Property value
157 * @throws ServiceValidationException the service validation exception
158 */
159 public <T> T getFieldValueOrThrowIfNull(Class<T> cls, Object value,
160 String name) throws ServiceValidationException {
161 if (value != null) {
162 return (T) value;
163 } else {
164 throw new ServiceValidationException(String.format(
165 "The recurrence pattern's %s property must be specified.",
166 name));
167 }
168 }
169
170 /**
171 * Gets the date and time when the recurrence start.
172 *
173 * @return Date
174 * @throws ServiceValidationException the service validation exception
175 */
176 public Date getStartDate() throws ServiceValidationException {
177 return this.getFieldValueOrThrowIfNull(Date.class, this.startDate,
178 "StartDate");
179
180 }
181
182 /**
183 * sets the date and time when the recurrence start.
184 *
185 * @param value the new start date
186 */
187 public void setStartDate(Date value) {
188 this.startDate = value;
189 }
190
191 /**
192 * Gets a value indicating whether the pattern has a fixed number of
193 * occurrences or an end date.
194 *
195 * @return boolean
196 */
197 public boolean hasEnd() {
198
199 return ((this.numberOfOccurrences != null) || (this.endDate != null));
200 }
201
202 /**
203 * Sets up this recurrence so that it never ends. Calling NeverEnds is
204 * equivalent to setting both NumberOfOccurrences and EndDate to null.
205 */
206 public void neverEnds() {
207 this.numberOfOccurrences = null;
208 this.endDate = null;
209 this.changed();
210 }
211
212 /**
213 * Validates this instance.
214 *
215 * @throws Exception
216 */
217 @Override
218 public void internalValidate() throws Exception {
219 super.internalValidate();
220
221 if (this.startDate == null) {
222 throw new ServiceValidationException("The recurrence pattern's StartDate property must be specified.");
223 }
224 }
225
226 /**
227 * Gets the number of occurrences after which the recurrence ends.
228 * Setting NumberOfOccurrences resets EndDate.
229 *
230 * @return the number of occurrences
231 */
232 public Integer getNumberOfOccurrences() {
233 return this.numberOfOccurrences;
234
235 }
236
237 /**
238 * Gets the number of occurrences after which the recurrence ends.
239 * Setting NumberOfOccurrences resets EndDate.
240 *
241 * @param value the new number of occurrences
242 * @throws ArgumentException the argument exception
243 */
244 public void setNumberOfOccurrences(Integer value) throws ArgumentException {
245 if (value < 1) {
246 throw new ArgumentException("NumberOfOccurrences must be greater than 0.");
247 }
248
249 if (this.canSetFieldValue(this.numberOfOccurrences, value)) {
250 numberOfOccurrences = value;
251 this.changed();
252 }
253
254 this.endDate = null;
255
256 }
257
258 /**
259 * Gets the date after which the recurrence ends. Setting EndDate resets
260 * NumberOfOccurrences.
261 *
262 * @return the end date
263 */
264 public Date getEndDate() {
265
266 return this.endDate;
267 }
268
269 /**
270 * sets the date after which the recurrence ends. Setting EndDate resets
271 * NumberOfOccurrences.
272 *
273 * @param value the new end date
274 */
275 public void setEndDate(Date value) {
276
277 if (this.canSetFieldValue(this.endDate, value)) {
278 this.endDate = value;
279 this.changed();
280 }
281
282 this.numberOfOccurrences = null;
283
284 }
285
286 /**
287 * Represents a recurrence pattern where each occurrence happens a specific
288 * number of days after the previous one.
289 */
290 public final static class DailyPattern extends IntervalPattern {
291
292 /**
293 * Gets the name of the XML element.
294 *
295 * @return the xml element name
296 */
297 @Override
298 public String getXmlElementName() {
299 return XmlElementNames.DailyRecurrence;
300 }
301
302 /**
303 * Initializes a new instance of the DailyPattern class.
304 */
305
306 public DailyPattern() {
307 super();
308 }
309
310 /**
311 * Initializes a new instance of the DailyPattern class.
312 *
313 * @param startDate The date and time when the recurrence starts.
314 * @param interval The number of days between each occurrence.
315 * @throws ArgumentOutOfRangeException the argument out of range exception
316 */
317 public DailyPattern(Date startDate, int interval)
318 throws ArgumentOutOfRangeException {
319 super(startDate, interval);
320 }
321
322 }
323
324
325 /**
326 * Represents a regeneration pattern, as used with recurring tasks, where
327 * each occurrence happens a specified number of days after the previous one
328 * is completed.
329 */
330
331 public final static class DailyRegenerationPattern extends IntervalPattern {
332
333 /**
334 * Initializes a new instance of the DailyRegenerationPattern class.
335 */
336 public DailyRegenerationPattern() {
337 super();
338 }
339
340 /**
341 * Initializes a new instance of the DailyRegenerationPattern class.
342 *
343 * @param startDate The date and time when the recurrence starts.
344 * @param interval The number of days between each occurrence.
345 * @throws ArgumentOutOfRangeException the argument out of range exception
346 */
347 public DailyRegenerationPattern(Date startDate, int interval)
348 throws ArgumentOutOfRangeException {
349 super(startDate, interval);
350
351 }
352
353 /**
354 * Gets the name of the XML element.
355 *
356 * @return the xml element name
357 */
358 public String getXmlElementName() {
359 return XmlElementNames.DailyRegeneration;
360 }
361
362 /**
363 * Gets a value indicating whether this instance is a regeneration
364 * pattern.
365 *
366 * @return true, if is regeneration pattern
367 */
368 public boolean isRegenerationPattern() {
369 return true;
370 }
371
372 }
373
374
375 /**
376 * Represents a recurrence pattern where each occurrence happens at a
377 * specific interval after the previous one.
378 * [EditorBrowsable(EditorBrowsableState.Never)]
379 */
380 @EditorBrowsable(state = EditorBrowsableState.Never)
381 public abstract static class IntervalPattern extends Recurrence {
382
383 /**
384 * The interval.
385 */
386 private int interval = 1;
387
388 /**
389 * Initializes a new instance of the IntervalPattern class.
390 */
391 public IntervalPattern() {
392 super();
393 }
394
395 /**
396 * Initializes a new instance of the IntervalPattern class.
397 *
398 * @param startDate The date and time when the recurrence starts.
399 * @param interval The number of days between each occurrence.
400 * @throws ArgumentOutOfRangeException the argument out of range exception
401 */
402 public IntervalPattern(Date startDate, int interval)
403 throws ArgumentOutOfRangeException {
404
405 super(startDate);
406 if (interval < 1) {
407 throw new ArgumentOutOfRangeException("interval", "The interval must be greater than or equal to 1.");
408 }
409
410 this.setInterval(interval);
411 }
412
413 /**
414 * Write property to XML.
415 *
416 * @param writer the writer
417 * @throws Exception the exception
418 */
419 @Override
420 public void internalWritePropertiesToXml(EwsServiceXmlWriter writer) throws Exception {
421 super.internalWritePropertiesToXml(writer);
422
423 writer.writeElementValue(XmlNamespace.Types,
424 XmlElementNames.Interval, this.getInterval());
425 }
426
427 /**
428 * Tries to read element from XML.
429 *
430 * @param reader the reader
431 * @return true, if successful
432 * @throws Exception the exception
433 */
434 @Override
435 public boolean tryReadElementFromXml(EwsServiceXmlReader reader)
436 throws Exception {
437 if (super.tryReadElementFromXml(reader)) {
438 return true;
439 } else {
440
441 if (reader.getLocalName().equals(XmlElementNames.Interval)) {
442 this.interval = reader.readElementValue(Integer.class);
443 return true;
444 } else {
445 return false;
446 }
447 }
448 }
449
450 /**
451 * Gets the interval between occurrences.
452 *
453 * @return the interval
454 */
455 public int getInterval() {
456 return this.interval;
457 }
458
459 /**
460 * Sets the interval.
461 *
462 * @param value the new interval
463 * @throws ArgumentOutOfRangeException the argument out of range exception
464 */
465 public void setInterval(int value) throws ArgumentOutOfRangeException {
466
467 if (value < 1) {
468 throw new ArgumentOutOfRangeException("value", "The interval must be greater than or equal to 1.");
469 }
470
471 if (this.canSetFieldValue(this.interval, value)) {
472 this.interval = value;
473 this.changed();
474 }
475
476 }
477
478 }
479
480
481 /**
482 * Represents a recurrence pattern where each occurrence happens on a
483 * specific day a specific number of months after the previous one.
484 */
485
486 public final static class MonthlyPattern extends IntervalPattern {
487
488 /**
489 * The day of month.
490 */
491 private Integer dayOfMonth;
492
493 /**
494 * Initializes a new instance of the MonthlyPattern class.
495 */
496 public MonthlyPattern() {
497 super();
498
499 }
500
501 /**
502 * Initializes a new instance of the MonthlyPattern class.
503 *
504 * @param startDate the start date
505 * @param interval the interval
506 * @param dayOfMonth the day of month
507 * @throws ArgumentOutOfRangeException the argument out of range exception
508 */
509 public MonthlyPattern(Date startDate, int interval, int dayOfMonth)
510 throws ArgumentOutOfRangeException {
511 super(startDate, interval);
512
513 this.setDayOfMonth(dayOfMonth);
514 }
515
516 // / Gets the name of the XML element.
517
518 /*
519 * (non-Javadoc)
520 *
521 * @see microsoft.exchange.webservices.Recurrence#getXmlElementName()
522 */
523 @Override
524 public String getXmlElementName() {
525 return XmlElementNames.AbsoluteMonthlyRecurrence;
526 }
527
528 /**
529 * Write property to XML.
530 *
531 * @param writer the writer
532 * @throws Exception the exception
533 */
534 @Override
535 public void internalWritePropertiesToXml(EwsServiceXmlWriter writer)
536 throws Exception {
537 super.internalWritePropertiesToXml(writer);
538
539 writer.writeElementValue(XmlNamespace.Types,
540 XmlElementNames.DayOfMonth, this.getDayOfMonth());
541 }
542
543 /**
544 * Tries to read element from XML.
545 *
546 * @param reader the reader
547 * @return True if appropriate element was read.
548 * @throws Exception the exception
549 */
550 @Override
551 public boolean tryReadElementFromXml(EwsServiceXmlReader reader)
552 throws Exception {
553 if (super.tryReadElementFromXml(reader)) {
554 return true;
555 } else {
556 if (reader.getLocalName().equals(XmlElementNames.DayOfMonth)) {
557 this.dayOfMonth = reader.readElementValue(Integer.class);
558 return true;
559 } else {
560 return false;
561 }
562 }
563 }
564
565 /**
566 * Validates this instance.
567 *
568 * @throws Exception
569 */
570 @Override
571 public void internalValidate() throws Exception {
572 super.internalValidate();
573
574 if (this.dayOfMonth == null) {
575 throw new ServiceValidationException("DayOfMonth must be between 1 and 31.");
576 }
577 }
578
579 /**
580 * Gets the day of month.
581 *
582 * @return the day of month
583 * @throws ServiceValidationException the service validation exception
584 */
585 public int getDayOfMonth() throws ServiceValidationException {
586 return this.getFieldValueOrThrowIfNull(Integer.class, this.dayOfMonth,
587 "DayOfMonth");
588
589 }
590
591 /**
592 * Sets the day of month.
593 *
594 * @param value the new day of month
595 * @throws ArgumentOutOfRangeException the argument out of range exception
596 */
597 public void setDayOfMonth(int value)
598 throws ArgumentOutOfRangeException {
599 if (value < 1 || value > 31) {
600 throw new ArgumentOutOfRangeException("DayOfMonth", "DayOfMonth must be between 1 and 31.");
601 }
602
603 if (this.canSetFieldValue(this.dayOfMonth, value)) {
604 this.dayOfMonth = value;
605 this.changed();
606 }
607 }
608 }
609
610
611 /**
612 * Represents a regeneration pattern, as used with recurring tasks, where
613 * each occurrence happens a specified number of months after the previous
614 * one is completed.
615 */
616 public final static class MonthlyRegenerationPattern extends
617 IntervalPattern {
618
619 /**
620 * Instantiates a new monthly regeneration pattern.
621 */
622 public MonthlyRegenerationPattern() {
623 super();
624
625 }
626
627 /**
628 * Instantiates a new monthly regeneration pattern.
629 *
630 * @param startDate the start date
631 * @param interval the interval
632 * @throws ArgumentOutOfRangeException the argument out of range exception
633 */
634 public MonthlyRegenerationPattern(Date startDate, int interval)
635 throws ArgumentOutOfRangeException {
636 super(startDate, interval);
637
638 }
639
640 /**
641 * Gets the name of the XML element. <value>The name of the XML
642 * element.</value>
643 *
644 * @return the xml element name
645 */
646 @Override
647 public String getXmlElementName() {
648 return XmlElementNames.MonthlyRegeneration;
649 }
650
651 /**
652 * Gets a value indicating whether this instance is regeneration
653 * pattern. <value> <c>true</c> if this instance is regeneration
654 * pattern; otherwise, <c>false</c>. </value>
655 *
656 * @return true, if is regeneration pattern
657 */
658 public boolean isRegenerationPattern() {
659 return true;
660 }
661 }
662
663
664 /**
665 * Represents a recurrence pattern where each occurrence happens on a
666 * relative day a specific number of months after the previous one.
667 */
668 public final static class RelativeMonthlyPattern extends IntervalPattern {
669
670 /**
671 * The day of the week.
672 */
673 private DayOfTheWeek dayOfTheWeek;
674
675 /**
676 * The day of the week index.
677 */
678 private DayOfTheWeekIndex dayOfTheWeekIndex;
679
680 // / Initializes a new instance of the <see
681 // cref="RelativeMonthlyPattern"/> class.
682
683 /**
684 * Instantiates a new relative monthly pattern.
685 */
686 public RelativeMonthlyPattern() {
687 super();
688 }
689
690 /**
691 * Instantiates a new relative monthly pattern.
692 *
693 * @param startDate the start date
694 * @param interval the interval
695 * @param dayOfTheWeek the day of the week
696 * @param dayOfTheWeekIndex the day of the week index
697 * @throws ArgumentOutOfRangeException the argument out of range exception
698 */
699 public RelativeMonthlyPattern(Date startDate, int interval,
700 DayOfTheWeek dayOfTheWeek, DayOfTheWeekIndex dayOfTheWeekIndex)
701 throws ArgumentOutOfRangeException {
702 super(startDate, interval);
703
704 this.setDayOfTheWeek(dayOfTheWeek);
705 this.setDayOfTheWeekIndex(dayOfTheWeekIndex);
706 }
707
708 /**
709 * Gets the name of the XML element.
710 *
711 * @return the xml element name
712 */
713 @Override
714 public String getXmlElementName() {
715 return XmlElementNames.RelativeMonthlyRecurrence;
716 }
717
718 /**
719 * Write property to XML.
720 *
721 * @param writer the writer
722 * @throws Exception the exception
723 */
724 @Override
725 public void internalWritePropertiesToXml(EwsServiceXmlWriter writer)
726 throws Exception {
727 super.internalWritePropertiesToXml(writer);
728
729 writer.writeElementValue(XmlNamespace.Types,
730 XmlElementNames.DaysOfWeek, this.getDayOfTheWeek());
731
732 writer
733 .writeElementValue(XmlNamespace.Types,
734 XmlElementNames.DayOfWeekIndex, this
735 .getDayOfTheWeekIndex());
736 }
737
738 /**
739 * Tries to read element from XML.
740 *
741 * @param reader the reader
742 * @return True if appropriate element was read.
743 * @throws Exception the exception
744 */
745 @Override
746 public boolean tryReadElementFromXml(EwsServiceXmlReader reader)
747 throws Exception {
748 if (super.tryReadElementFromXml(reader)) {
749 return true;
750 } else {
751 if (reader.getLocalName().equals(XmlElementNames.DaysOfWeek)) {
752
753 this.dayOfTheWeek = reader
754 .readElementValue(DayOfTheWeek.class);
755 return true;
756 } else if (reader.getLocalName().equals(
757 XmlElementNames.DayOfWeekIndex)) {
758
759 this.dayOfTheWeekIndex = reader
760 .readElementValue(DayOfTheWeekIndex.class);
761 return true;
762 } else {
763
764 return false;
765 }
766 }
767 }
768
769 /**
770 * Validates this instance.
771 *
772 * @throws Exception
773 */
774 @Override
775 public void internalValidate() throws Exception {
776 super.internalValidate();
777
778 if (this.dayOfTheWeek == null) {
779 throw new ServiceValidationException(
780 "The recurrence pattern's property DayOfTheWeek must be specified.");
781 }
782
783 if (this.dayOfTheWeekIndex == null) {
784 throw new ServiceValidationException(
785 "The recurrence pattern's DayOfWeekIndex property must be specified.");
786 }
787 }
788
789 /**
790 * Day of the week index.
791 *
792 * @return the day of the week index
793 * @throws ServiceValidationException the service validation exception
794 */
795 public DayOfTheWeekIndex getDayOfTheWeekIndex()
796 throws ServiceValidationException {
797 return this.getFieldValueOrThrowIfNull(DayOfTheWeekIndex.class,
798 this.dayOfTheWeekIndex, "DayOfTheWeekIndex");
799 }
800
801 /**
802 * Day of the week index.
803 *
804 * @param value the value
805 */
806 public void setDayOfTheWeekIndex(DayOfTheWeekIndex value) {
807 if (this.canSetFieldValue(this.dayOfTheWeekIndex, value)) {
808 this.dayOfTheWeekIndex = value;
809 this.changed();
810 }
811
812 }
813
814 /**
815 * Gets the day of the week.
816 *
817 * @return the day of the week
818 * @throws ServiceValidationException the service validation exception
819 */
820 public DayOfTheWeek getDayOfTheWeek()
821 throws ServiceValidationException {
822 return this.getFieldValueOrThrowIfNull(DayOfTheWeek.class,
823 this.dayOfTheWeek, "DayOfTheWeek");
824
825 }
826
827 /**
828 * Sets the day of the week.
829 *
830 * @param value the new day of the week
831 */
832 public void setDayOfTheWeek(DayOfTheWeek value) {
833
834 if (this.canSetFieldValue(this.dayOfTheWeek, value)) {
835 this.dayOfTheWeek = value;
836 this.changed();
837 }
838 }
839 }
840
841
842 /**
843 * The Class RelativeYearlyPattern.
844 */
845 public final static class RelativeYearlyPattern extends Recurrence {
846
847 /**
848 * The day of the week.
849 */
850 private DayOfTheWeek dayOfTheWeek;
851
852 /**
853 * The day of the week index.
854 */
855 private DayOfTheWeekIndex dayOfTheWeekIndex;
856
857 /**
858 * The month.
859 */
860 private Month month;
861
862 /**
863 * Gets the name of the XML element. <value>The name of the XML
864 * element.</value>
865 *
866 * @return the xml element name
867 */
868 @Override
869 public String getXmlElementName() {
870 return XmlElementNames.RelativeYearlyRecurrence;
871 }
872
873 /**
874 * Write property to XML.
875 *
876 * @param writer the writer
877 * @throws Exception the exception
878 */
879 @Override
880 public void internalWritePropertiesToXml(EwsServiceXmlWriter writer)
881 throws Exception {
882 super.internalWritePropertiesToXml(writer);
883
884 writer.writeElementValue(XmlNamespace.Types,
885 XmlElementNames.DaysOfWeek, this.dayOfTheWeek);
886
887 writer.writeElementValue(XmlNamespace.Types,
888 XmlElementNames.DayOfWeekIndex, this.dayOfTheWeekIndex);
889
890 writer.writeElementValue(XmlNamespace.Types, XmlElementNames.Month,
891 this.month);
892 }
893
894 /**
895 * Tries to read element from XML.
896 *
897 * @param reader the reader
898 * @return True if element was read.
899 * @throws Exception the exception
900 */
901 @Override
902 public boolean tryReadElementFromXml(EwsServiceXmlReader reader)
903 throws Exception {
904 if (super.tryReadElementFromXml(reader)) {
905 return true;
906 } else {
907 if (reader.getLocalName().equals(XmlElementNames.DaysOfWeek)) {
908
909 this.dayOfTheWeek = reader
910 .readElementValue(DayOfTheWeek.class);
911 return true;
912 } else if (reader.getLocalName().equals(
913 XmlElementNames.DayOfWeekIndex)) {
914
915 this.dayOfTheWeekIndex = reader
916 .readElementValue(DayOfTheWeekIndex.class);
917 return true;
918 } else if (reader.getLocalName().equals(XmlElementNames.Month)) {
919
920 this.month = reader.readElementValue(Month.class);
921 return true;
922 } else {
923
924 return false;
925 }
926 }
927 }
928
929 /**
930 * Instantiates a new relative yearly pattern.
931 */
932 public RelativeYearlyPattern() {
933 super();
934
935 }
936
937 /**
938 * Instantiates a new relative yearly pattern.
939 *
940 * @param startDate the start date
941 * @param month the month
942 * @param dayOfTheWeek the day of the week
943 * @param dayOfTheWeekIndex the day of the week index
944 */
945 public RelativeYearlyPattern(Date startDate, Month month,
946 DayOfTheWeek dayOfTheWeek,
947 DayOfTheWeekIndex dayOfTheWeekIndex) {
948 super(startDate);
949
950 this.month = month;
951 this.dayOfTheWeek = dayOfTheWeek;
952 this.dayOfTheWeekIndex = dayOfTheWeekIndex;
953 }
954
955 /**
956 * Validates this instance.
957 *
958 * @throws Exception
959 */
960 @Override
961 public void internalValidate() throws Exception {
962 super.internalValidate();
963
964 if (this.dayOfTheWeekIndex == null) {
965 throw new ServiceValidationException(
966 "The recurrence pattern's DayOfWeekIndex property must be specified.");
967 }
968
969 if (this.dayOfTheWeek == null) {
970 throw new ServiceValidationException(
971 "The recurrence pattern's property DayOfTheWeek must be specified.");
972 }
973
974 if (this.month == null) {
975 throw new ServiceValidationException("The recurrence pattern's Month property must be specified.");
976 }
977 }
978
979 /**
980 * Gets the relative position of the day specified in DayOfTheWeek
981 * within the month.
982 *
983 * @return the day of the week index
984 * @throws ServiceValidationException the service validation exception
985 */
986 public DayOfTheWeekIndex getDayOfTheWeekIndex()
987 throws ServiceValidationException {
988
989 return this.getFieldValueOrThrowIfNull(DayOfTheWeekIndex.class,
990 this.dayOfTheWeekIndex, "DayOfTheWeekIndex");
991 }
992
993 /**
994 * Sets the relative position of the day specified in DayOfTheWeek
995 * within the month.
996 *
997 * @param value the new day of the week index
998 */
999 public void setDayOfTheWeekIndex(DayOfTheWeekIndex value) {
1000
1001 if (this.canSetFieldValue(this.dayOfTheWeekIndex, value)) {
1002 this.dayOfTheWeekIndex = value;
1003 this.changed();
1004 }
1005 }
1006
1007 /**
1008 * Gets the day of the week.
1009 *
1010 * @return the day of the week
1011 * @throws ServiceValidationException the service validation exception
1012 */
1013 public DayOfTheWeek getDayOfTheWeek()
1014 throws ServiceValidationException {
1015
1016 return this.getFieldValueOrThrowIfNull(DayOfTheWeek.class,
1017 this.dayOfTheWeek, "DayOfTheWeek");
1018 }
1019
1020 /**
1021 * Sets the day of the week.
1022 *
1023 * @param value the new day of the week
1024 */
1025 public void setDayOfTheWeek(DayOfTheWeek value) {
1026
1027 if (this.canSetFieldValue(this.dayOfTheWeek, value)) {
1028 this.dayOfTheWeek = value;
1029 this.changed();
1030 }
1031 }
1032
1033 /**
1034 * Gets the month.
1035 *
1036 * @return the month
1037 * @throws ServiceValidationException the service validation exception
1038 */
1039 public Month getMonth() throws ServiceValidationException {
1040
1041 return this.getFieldValueOrThrowIfNull(Month.class, this.month,
1042 "Month");
1043
1044 }
1045
1046 /**
1047 * Sets the month.
1048 *
1049 * @param value the new month
1050 */
1051 public void setMonth(Month value) {
1052
1053 if (this.canSetFieldValue(this.month, value)) {
1054 this.month = value;
1055 this.changed();
1056 }
1057 }
1058 }
1059
1060
1061 /**
1062 * Represents a recurrence pattern where each occurrence happens on specific
1063 * days a specific number of weeks after the previous one.
1064 */
1065 public final static class WeeklyPattern extends IntervalPattern implements IComplexPropertyChangedDelegate {
1066
1067 /**
1068 * The days of the week.
1069 */
1070 private DayOfTheWeekCollection daysOfTheWeek =
1071 new DayOfTheWeekCollection();
1072
1073 private Calendar firstDayOfWeek;
1074
1075 /**
1076 * Initializes a new instance of the WeeklyPattern class. specific days
1077 * a specific number of weeks after the previous one.
1078 */
1079 public WeeklyPattern() {
1080 super();
1081
1082 this.daysOfTheWeek.addOnChangeEvent(this);
1083 }
1084
1085 /**
1086 * Initializes a new instance of the WeeklyPattern class.
1087 *
1088 * @param startDate the start date
1089 * @param interval the interval
1090 * @param daysOfTheWeek the days of the week
1091 * @throws ArgumentOutOfRangeException the argument out of range exception
1092 */
1093 public WeeklyPattern(Date startDate, int interval,
1094 DayOfTheWeek... daysOfTheWeek)
1095 throws ArgumentOutOfRangeException {
1096 super(startDate, interval);
1097
1098 ArrayList<DayOfTheWeek> toProcess = new ArrayList<DayOfTheWeek>(
1099 Arrays.asList(daysOfTheWeek));
1100 Iterator<DayOfTheWeek> idaysOfTheWeek = toProcess.iterator();
1101 this.daysOfTheWeek.addRange(idaysOfTheWeek);
1102 }
1103
1104 /**
1105 * Change event handler.
1106 *
1107 * @param complexProperty the complex property
1108 */
1109 private void daysOfTheWeekChanged(ComplexProperty complexProperty) {
1110 this.changed();
1111 }
1112
1113 /**
1114 * Gets the name of the XML element. <value>The name of the XML
1115 * element.</value>
1116 *
1117 * @return the xml element name
1118 */
1119 @Override
1120 public String getXmlElementName() {
1121 return XmlElementNames.WeeklyRecurrence;
1122 }
1123
1124 /**
1125 * Write property to XML.
1126 *
1127 * @param writer the writer
1128 * @throws Exception the exception
1129 */
1130 @Override
1131 public void internalWritePropertiesToXml(EwsServiceXmlWriter writer)
1132 throws Exception {
1133 super.internalWritePropertiesToXml(writer);
1134
1135 this.getDaysOfTheWeek().writeToXml(writer,
1136 XmlElementNames.DaysOfWeek);
1137 if (this.firstDayOfWeek != null) {
1138
1139 EwsUtilities
1140 .validatePropertyVersion((ExchangeService) writer.getService(), ExchangeVersion.Exchange2010_SP1,
1141 "FirstDayOfWeek");
1142
1143 writer.writeElementValue(
1144 XmlNamespace.Types,
1145 XmlElementNames.FirstDayOfWeek,
1146 this.firstDayOfWeek);
1147 }
1148
1149 }
1150
1151 /**
1152 * Tries to read element from XML.
1153 *
1154 * @param reader the reader
1155 * @return True if appropriate element was read.
1156 * @throws Exception the exception
1157 */
1158 @Override
1159 public boolean tryReadElementFromXml(EwsServiceXmlReader reader)
1160 throws Exception {
1161 if (super.tryReadElementFromXml(reader)) {
1162 return true;
1163 } else {
1164 if (reader.getLocalName().equals(XmlElementNames.DaysOfWeek)) {
1165
1166 this.getDaysOfTheWeek().loadFromXml(reader,
1167 reader.getLocalName());
1168 return true;
1169 } else if (reader.getLocalName().equals(XmlElementNames.FirstDayOfWeek)) {
1170 this.firstDayOfWeek = reader.
1171 readElementValue(Calendar.class,
1172 XmlNamespace.Types,
1173 XmlElementNames.FirstDayOfWeek);
1174 return true;
1175 } else {
1176
1177 return false;
1178 }
1179 }
1180 }
1181
1182 /**
1183 * Validates this instance.
1184 *
1185 * @throws Exception
1186 */
1187 @Override
1188 public void internalValidate() throws Exception {
1189 super.internalValidate();
1190
1191 if (this.getDaysOfTheWeek().getCount() == 0) {
1192 throw new ServiceValidationException(
1193 "The recurrence pattern's property DaysOfTheWeek must contain at least one day of the week.");
1194 }
1195 }
1196
1197 /**
1198 * Gets the list of the days of the week when occurrences happen.
1199 *
1200 * @return the days of the week
1201 */
1202 public DayOfTheWeekCollection getDaysOfTheWeek() {
1203 return this.daysOfTheWeek;
1204 }
1205
1206 public Calendar getFirstDayOfWeek() throws ServiceValidationException {
1207 return this.getFieldValueOrThrowIfNull(Calendar.class,
1208 this.firstDayOfWeek, "FirstDayOfWeek");
1209 }
1210
1211 public void setFirstDayOfWeek(Calendar value) {
1212 if (this.canSetFieldValue(this.firstDayOfWeek, value)) {
1213 this.firstDayOfWeek = value;
1214 this.changed();
1215 }
1216 }
1217
1218 /*
1219 * (non-Javadoc)
1220 *
1221 * @see
1222 * microsoft.exchange.webservices.
1223 * ComplexPropertyChangedDelegateInterface#
1224 * complexPropertyChanged(microsoft.exchange.webservices.ComplexProperty
1225 * )
1226 */
1227 @Override
1228 public void complexPropertyChanged(ComplexProperty complexProperty) {
1229 this.daysOfTheWeekChanged(complexProperty);
1230 }
1231
1232 }
1233
1234
1235 /**
1236 * Represents a regeneration pattern, as used with recurring tasks, where
1237 * each occurrence happens a specified number of weeks after the previous
1238 * one is completed.
1239 */
1240 public final static class WeeklyRegenerationPattern extends
1241 IntervalPattern {
1242
1243 /**
1244 * Initializes a new instance of the WeeklyRegenerationPattern class.
1245 */
1246 public WeeklyRegenerationPattern() {
1247
1248 super();
1249 }
1250
1251 /**
1252 * Initializes a new instance of the WeeklyRegenerationPattern class.
1253 *
1254 * @param startDate the start date
1255 * @param interval the interval
1256 * @throws ArgumentOutOfRangeException the argument out of range exception
1257 */
1258 public WeeklyRegenerationPattern(Date startDate, int interval)
1259 throws ArgumentOutOfRangeException {
1260 super(startDate, interval);
1261
1262 }
1263
1264 /**
1265 * Gets the name of the XML element. <value>The name of the XML
1266 * element.</value>
1267 *
1268 * @return the xml element name
1269 */
1270 @Override
1271 public String getXmlElementName() {
1272 return XmlElementNames.WeeklyRegeneration;
1273 }
1274
1275 /**
1276 * Gets a value indicating whether this instance is regeneration
1277 * pattern. <value> <c>true</c> if this instance is regeneration
1278 * pattern; otherwise, <c>false</c>. </value>
1279 *
1280 * @return true, if is regeneration pattern
1281 */
1282 public boolean isRegenerationPattern() {
1283 return true;
1284 }
1285 }
1286
1287
1288 /**
1289 * Represents a recurrence pattern where each occurrence happens on a
1290 * specific day every year.
1291 */
1292 public final static class YearlyPattern extends Recurrence {
1293
1294 /**
1295 * The month.
1296 */
1297 private Month month;
1298
1299 /**
1300 * The day of month.
1301 */
1302 private Integer dayOfMonth;
1303
1304 /**
1305 * Initializes a new instance of the YearlyPattern class.
1306 */
1307 public YearlyPattern() {
1308 super();
1309
1310 }
1311
1312 /**
1313 * Initializes a new instance of the YearlyPattern class.
1314 *
1315 * @param startDate the start date
1316 * @param month the month
1317 * @param dayOfMonth the day of month
1318 */
1319 public YearlyPattern(Date startDate, Month month, int dayOfMonth) {
1320 super(startDate);
1321
1322 this.month = month;
1323 this.dayOfMonth = dayOfMonth;
1324 }
1325
1326 /**
1327 * Gets the name of the XML element. <value>The name of the XML
1328 * element.</value>
1329 *
1330 * @return the xml element name
1331 */
1332 @Override
1333 public String getXmlElementName() {
1334 return XmlElementNames.AbsoluteYearlyRecurrence;
1335 }
1336
1337 /**
1338 * Write property to XML.
1339 *
1340 * @param writer the writer
1341 * @throws Exception the exception
1342 */
1343 @Override
1344 public void internalWritePropertiesToXml(EwsServiceXmlWriter writer)
1345 throws Exception {
1346 super.internalWritePropertiesToXml(writer);
1347
1348 writer.writeElementValue(XmlNamespace.Types,
1349 XmlElementNames.DayOfMonth, this.getDayOfMonth());
1350
1351 writer.writeElementValue(XmlNamespace.Types, XmlElementNames.Month,
1352 this.getMonth());
1353 }
1354
1355 /**
1356 * Tries to read element from XML.
1357 *
1358 * @param reader the reader
1359 * @return True if element was read
1360 * @throws Exception the exception
1361 */
1362 @Override
1363 public boolean tryReadElementFromXml(EwsServiceXmlReader reader)
1364 throws Exception {
1365 if (super.tryReadElementFromXml(reader)) {
1366 return true;
1367 } else {
1368 if (reader.getLocalName().equals(XmlElementNames.DayOfMonth)) {
1369
1370 this.dayOfMonth = reader.readElementValue(Integer.class);
1371 return true;
1372 } else if (reader.getLocalName().equals(XmlElementNames.Month)) {
1373
1374 this.month = reader.readElementValue(Month.class);
1375 return true;
1376 } else {
1377
1378 return false;
1379 }
1380 }
1381 }
1382
1383 /**
1384 * Validates this instance.
1385 *
1386 * @throws Exception
1387 */
1388 @Override
1389 public void internalValidate() throws Exception {
1390 super.internalValidate();
1391
1392 if (this.month == null) {
1393 throw new ServiceValidationException("The recurrence pattern's Month property must be specified.");
1394 }
1395
1396 if (this.dayOfMonth == null) {
1397 throw new ServiceValidationException(
1398 "The recurrence pattern's DayOfMonth property must be specified.");
1399 }
1400 }
1401
1402 /**
1403 * Gets the month of the year when each occurrence happens.
1404 *
1405 * @return the month
1406 * @throws ServiceValidationException the service validation exception
1407 */
1408 public Month getMonth() throws ServiceValidationException {
1409 return this.getFieldValueOrThrowIfNull(Month.class, this.month,
1410 "Month");
1411 }
1412
1413 /**
1414 * Sets the month.
1415 *
1416 * @param value the new month
1417 */
1418 public void setMonth(Month value) {
1419
1420 if (this.canSetFieldValue(this.month, value)) {
1421 this.month = value;
1422 this.changed();
1423 }
1424 }
1425
1426 /**
1427 * Gets the day of the month when each occurrence happens. DayOfMonth
1428 * must be between 1 and 31.
1429 *
1430 * @return the day of month
1431 * @throws ServiceValidationException the service validation exception
1432 */
1433 public int getDayOfMonth() throws ServiceValidationException {
1434
1435 return this.getFieldValueOrThrowIfNull(Integer.class, this.dayOfMonth,
1436 "DayOfMonth");
1437
1438 }
1439
1440 /**
1441 * Sets the day of the month when each occurrence happens. DayOfMonth
1442 * must be between 1 and 31.
1443 *
1444 * @param value the new day of month
1445 * @throws ArgumentOutOfRangeException the argument out of range exception
1446 */
1447 public void setDayOfMonth(int value)
1448 throws ArgumentOutOfRangeException {
1449
1450 if (value < 1 || value > 31) {
1451 throw new ArgumentOutOfRangeException("DayOfMonth", "DayOfMonth must be between 1 and 31.");
1452 }
1453
1454 if (this.canSetFieldValue(this.dayOfMonth, value)) {
1455 this.dayOfMonth = value;
1456 this.changed();
1457 }
1458 }
1459 }
1460
1461
1462 /**
1463 * Represents a regeneration pattern, as used with recurring tasks, where
1464 * each occurrence happens a specified number of years after the previous
1465 * one is completed.
1466 */
1467 public final static class YearlyRegenerationPattern extends
1468 IntervalPattern {
1469
1470 /**
1471 * Gets the name of the XML element. <value>The name of the XML
1472 * element.</value>
1473 *
1474 * @return the xml element name
1475 */
1476 @Override
1477 public String getXmlElementName() {
1478 return XmlElementNames.YearlyRegeneration;
1479 }
1480
1481 /**
1482 * Gets a value indicating whether this instance is regeneration
1483 * pattern.
1484 *
1485 * @return true, if is regeneration pattern
1486 */
1487 public boolean isRegenerationPattern() {
1488 return true;
1489 }
1490
1491 /**
1492 * Initializes a new instance of the YearlyRegenerationPattern class.
1493 */
1494 public YearlyRegenerationPattern() {
1495 super();
1496
1497 }
1498
1499 /**
1500 * Initializes a new instance of the YearlyRegenerationPattern class.
1501 *
1502 * @param startDate the start date
1503 * @param interval the interval
1504 * @throws ArgumentOutOfRangeException the argument out of range exception
1505 */
1506 public YearlyRegenerationPattern(Date startDate, int interval)
1507 throws ArgumentOutOfRangeException {
1508 super(startDate, interval);
1509
1510 }
1511 }
1512 }