View Javadoc
1   /*
2    * DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
3    * Copyright (C) 2010  Mickael Guessant
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU General Public License
7    * as published by the Free Software Foundation; either version 2
8    * of the License, or (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, write to the Free Software
17   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18   */
19  
20  package davmail.exchange.ews;
21  
22  import davmail.exchange.ExchangeSession;
23  import org.apache.log4j.Logger;
24  
25  import java.io.IOException;
26  import java.io.Writer;
27  import java.text.SimpleDateFormat;
28  import java.util.Date;
29  import java.util.HashMap;
30  import java.util.HashSet;
31  import java.util.Locale;
32  
33  /**
34   * Handle calendar item recurrence update
35   */
36  public class RecurrenceFieldUpdate extends FieldUpdate {
37      public static final Logger LOGGER = Logger.getLogger(RecurrenceFieldUpdate.class);
38      static final HashMap<String, String> calDayToDayOfWeek = new HashMap<>();
39      static {
40          calDayToDayOfWeek.put("SU", "Sunday");
41          calDayToDayOfWeek.put("MO", "Monday");
42          calDayToDayOfWeek.put("TU", "Tuesday");
43          calDayToDayOfWeek.put("WE", "Wednesday");
44          calDayToDayOfWeek.put("TH", "Thursday");
45          calDayToDayOfWeek.put("FR", "Friday");
46          calDayToDayOfWeek.put("SA", "Saturday");
47      }
48      protected Date startDate;
49      protected Date endDate;
50      protected HashSet<String> byDays = null;
51  
52      public void setStartDate(Date startDate) {
53          this.startDate = startDate;
54      }
55  
56      public void setEndDate(Date endDate) {
57          this.endDate = endDate;
58      }
59  
60      public void setByDay(String[] days) {
61          byDays = new HashSet<>();
62          for (String day: days) {
63              String value = calDayToDayOfWeek.get(day);
64              if (value == null) {
65                  LOGGER.warn("Invalid day value: "+day);
66              } else {
67                  byDays.add(value);
68              }
69          }
70          // fix recurrence for Thunderbird weekday pattern
71          if (recurrencePattern == RecurrencePattern.DailyRecurrence) {
72              recurrencePattern = RecurrencePattern.WeeklyRecurrence;
73          }
74      }
75  
76      public enum RecurrencePattern {DailyRecurrence, WeeklyRecurrence,  AbsoluteMonthlyRecurrence, AbsoluteYearlyRecurrence}
77  
78      RecurrencePattern recurrencePattern;
79      int recurrenceInterval = 1;
80  
81      /**
82       * Create recurrence field update.
83       */
84      public RecurrenceFieldUpdate() {
85      }
86  
87      public void setRecurrencePattern(RecurrencePattern recurrencePattern) {
88          this.recurrencePattern = recurrencePattern;
89      }
90  
91      public void setRecurrencePattern(String value) {
92          if ("DAILY".equals(value)) {
93              setRecurrencePattern(RecurrenceFieldUpdate.RecurrencePattern.DailyRecurrence);
94          } else if ("WEEKLY".equals(value)) {
95              setRecurrencePattern(RecurrencePattern.WeeklyRecurrence);
96          } else if ("MONTHLY".equals(value)) {
97              setRecurrencePattern(RecurrencePattern.AbsoluteMonthlyRecurrence);
98          } else if ("YEARLY".equals(value)) {
99              setRecurrencePattern(RecurrencePattern.AbsoluteYearlyRecurrence);
100         }
101     }
102 
103     public void setRecurrenceInterval(String interval) {
104         this.recurrenceInterval = Integer.parseInt(interval);
105     }
106 
107     /**
108      * Write field to request writer.
109      *
110      * @param itemType item type
111      * @param writer   request writer
112      * @throws IOException on error
113      */
114     public void write(String itemType, Writer writer) throws IOException {
115         if (itemType != null) {
116             writer.write("<t:Set");
117             writer.write(itemType);
118             writer.write("Field>");
119         }
120 
121         // do not try to set empty value on create
122         if (itemType != null) {
123             writer.write("<t:FieldURI FieldURI=\"calendar:Recurrence\"/>");
124             writer.write("<t:CalendarItem>");
125 
126             writer.write("<t:Recurrence>");
127             writer.write("<t:");
128             writer.write(recurrencePattern.toString());
129             writer.write(">");
130             if (recurrencePattern == RecurrencePattern.AbsoluteYearlyRecurrence) {
131                 writeDayOfMonth(writer);
132                 writeMonth(writer);
133             } else if (recurrencePattern == RecurrencePattern.AbsoluteMonthlyRecurrence) {
134                 writeInterval(writer);
135                 writeDayOfMonth(writer);
136             } else if (recurrencePattern == RecurrencePattern.WeeklyRecurrence) {
137                 writeInterval(writer);
138                 writeDaysOfWeek(writer);
139             } else if (recurrencePattern == RecurrencePattern.DailyRecurrence) {
140                 writeInterval(writer);
141             }
142             writer.write("</t:");
143             writer.write(recurrencePattern.toString());
144             writer.write(">");
145             writeStartEnd(writer);
146             writer.write("</t:Recurrence>");
147 
148             writer.write("</t:CalendarItem>");
149         }
150 
151         if (itemType != null) {
152             writer.write("</t:Set");
153             writer.write(itemType);
154             writer.write("Field>");
155         }
156     }
157 
158     private void writeInterval(Writer writer) throws IOException {
159         writer.write("<t:Interval>");
160         writer.write(String.valueOf(recurrenceInterval));
161         writer.write("</t:Interval>");
162     }
163 
164     private void writeStartEnd(Writer writer) throws IOException {
165         if (endDate == null) {
166             writer.write("<t:NoEndRecurrence><t:StartDate>");
167             writer.write(getFormattedDate(startDate));
168             writer.write("</t:StartDate></t:NoEndRecurrence>");
169         } else {
170             writer.write("<t:EndDateRecurrence>");
171             writer.write("<t:StartDate>");
172             writer.write(getFormattedDate(startDate));
173             writer.write("</t:StartDate>");
174             writer.write("<t:EndDate>");
175             writer.write(getFormattedDate(endDate));
176             writer.write("</t:EndDate>");
177             writer.write("</t:EndDateRecurrence>");
178 
179         }
180     }
181 
182     private void writeDaysOfWeek(Writer writer) throws IOException {
183         writer.write("<t:DaysOfWeek>");
184         if (byDays != null) {
185             boolean first = true;
186             for (String dayOfeek:byDays) {
187                 if (first) {
188                     first = false;
189                 } else {
190                     writer.write(' ');
191                 }
192                 writer.write(dayOfeek);
193             }
194         } else {
195             writer.write(getDayOfWeek());
196         }
197         writer.write("</t:DaysOfWeek>");
198     }
199 
200     private void writeDayOfMonth(Writer writer) throws IOException {
201         writer.write("<t:DayOfMonth>");
202         writer.write(getDayOfMonth());
203         writer.write("</t:DayOfMonth>");
204     }
205 
206     private void writeMonth(Writer writer) throws IOException {
207         writer.write("<t:Month>");
208         writer.write(getMonth());
209         writer.write("</t:Month>");
210     }
211 
212     private String getDayOfWeek() {
213         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEEE", Locale.ENGLISH);
214         simpleDateFormat.setTimeZone(ExchangeSession.GMT_TIMEZONE);
215         return simpleDateFormat.format(startDate);
216     }
217 
218     private String getMonth() {
219         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MMMMM", Locale.ENGLISH);
220         simpleDateFormat.setTimeZone(ExchangeSession.GMT_TIMEZONE);
221         return simpleDateFormat.format(startDate);
222     }
223 
224     private String getDayOfMonth() {
225         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("d", Locale.ENGLISH);
226         simpleDateFormat.setTimeZone(ExchangeSession.GMT_TIMEZONE);
227         return simpleDateFormat.format(startDate);
228     }
229 
230     private String getFormattedDate(Date date) {
231         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
232         simpleDateFormat.setTimeZone(ExchangeSession.GMT_TIMEZONE);
233         return simpleDateFormat.format(date);
234     }
235 
236 }