src/net/fortuna/ical4j/model/Recur.java

changeset 3
73bdfa70b04e
parent 0
fb9019fb1bf7
     1.1 --- a/src/net/fortuna/ical4j/model/Recur.java	Tue Feb 10 19:25:00 2015 +0100
     1.2 +++ b/src/net/fortuna/ical4j/model/Recur.java	Tue Feb 10 19:38:00 2015 +0100
     1.3 @@ -44,6 +44,7 @@
     1.4  import java.util.StringTokenizer;
     1.5  
     1.6  import net.fortuna.ical4j.model.parameter.Value;
     1.7 +import net.fortuna.ical4j.util.CompatibilityHints;
     1.8  import net.fortuna.ical4j.util.Configurator;
     1.9  import net.fortuna.ical4j.util.Dates;
    1.10  
    1.11 @@ -171,6 +172,8 @@
    1.12      private NumberList setPosList;
    1.13  
    1.14      private String weekStartDay;
    1.15 +    
    1.16 +    private int calendarWeekStartDay;
    1.17  
    1.18      private Map experimentalValues = new HashMap();
    1.19  
    1.20 @@ -181,6 +184,8 @@
    1.21       * Default constructor.
    1.22       */
    1.23      public Recur() {
    1.24 +        // default week start is Monday per RFC5545
    1.25 +        calendarWeekStartDay = Calendar.MONDAY;
    1.26      }
    1.27      
    1.28      /**
    1.29 @@ -189,6 +194,8 @@
    1.30       * @throws ParseException thrown when the specified string contains an invalid representation of an UNTIL date value
    1.31       */
    1.32      public Recur(final String aValue) throws ParseException {
    1.33 +        // default week start is Monday per RFC5545
    1.34 +        calendarWeekStartDay = Calendar.MONDAY;
    1.35          final StringTokenizer t = new StringTokenizer(aValue, ";=");
    1.36          while (t.hasMoreTokens()) {
    1.37              final String token = t.nextToken();
    1.38 @@ -241,10 +248,17 @@
    1.39              }
    1.40              else if (WKST.equals(token)) {
    1.41                  weekStartDay = nextToken(t, token);
    1.42 +                calendarWeekStartDay = WeekDay.getCalendarDay(new WeekDay(weekStartDay));
    1.43              }
    1.44 -            // assume experimental value..
    1.45              else {
    1.46 -                experimentalValues.put(token, nextToken(t, token));
    1.47 +            	if (CompatibilityHints.isHintEnabled(CompatibilityHints.KEY_RELAXED_PARSING)) {
    1.48 +	            	// assume experimental value..
    1.49 +	                experimentalValues.put(token, nextToken(t, token));
    1.50 +            	}
    1.51 +            	else {
    1.52 +            		throw new IllegalArgumentException("Invalid recurrence rule part: " + 
    1.53 +            				token + "=" + nextToken(t, token));
    1.54 +            	}
    1.55              }
    1.56          }
    1.57          validateFrequency();
    1.58 @@ -264,6 +278,8 @@
    1.59       * @param until maximum recurrence date
    1.60       */
    1.61      public Recur(final String frequency, final Date until) {
    1.62 +        // default week start is Monday per RFC5545
    1.63 +        calendarWeekStartDay = Calendar.MONDAY;
    1.64          this.frequency = frequency;
    1.65          this.until = until;
    1.66          validateFrequency();
    1.67 @@ -274,6 +290,8 @@
    1.68       * @param count maximum recurrence count
    1.69       */
    1.70      public Recur(final String frequency, final int count) {
    1.71 +        // default week start is Monday per RFC5545
    1.72 +        calendarWeekStartDay = Calendar.MONDAY;
    1.73          this.frequency = frequency;
    1.74          this.count = count;
    1.75          validateFrequency();
    1.76 @@ -416,6 +434,9 @@
    1.77       */
    1.78      public final void setWeekStartDay(final String weekStartDay) {
    1.79          this.weekStartDay = weekStartDay;
    1.80 +        if (weekStartDay != null) {
    1.81 +            calendarWeekStartDay = WeekDay.getCalendarDay(new WeekDay(weekStartDay));
    1.82 +        }
    1.83      }
    1.84  
    1.85      /**
    1.86 @@ -578,8 +599,7 @@
    1.87                  dates.setTimeZone(((DateTime) seed).getTimeZone());
    1.88              }
    1.89          }
    1.90 -        final Calendar cal = Dates.getCalendarInstance(seed);
    1.91 -        cal.setTime(seed);
    1.92 +        final Calendar cal = getCalendarInstance(seed, true);
    1.93  
    1.94          // optimize the start time for selecting candidates
    1.95          // (only applicable where a COUNT is not specified)
    1.96 @@ -670,8 +690,7 @@
    1.97       */
    1.98      public final Date getNextDate(final Date seed, final Date startDate) {
    1.99  
   1.100 -        final Calendar cal = Dates.getCalendarInstance(seed);
   1.101 -        cal.setTime(seed);
   1.102 +        final Calendar cal = getCalendarInstance(seed, true);
   1.103  
   1.104          // optimize the start time for selecting candidates
   1.105          // (only applicable where a COUNT is not specified)
   1.106 @@ -857,8 +876,8 @@
   1.107          final DateList monthlyDates = getDateListInstance(dates);
   1.108          for (final Iterator i = dates.iterator(); i.hasNext();) {
   1.109              final Date date = (Date) i.next();
   1.110 -            final Calendar cal = Dates.getCalendarInstance(date);
   1.111 -            cal.setTime(date);
   1.112 +            final Calendar cal = getCalendarInstance(date, true);
   1.113 +
   1.114              for (final Iterator j = getMonthList().iterator(); j.hasNext();) {
   1.115                  final Integer month = (Integer) j.next();
   1.116                  // Java months are zero-based..
   1.117 @@ -883,8 +902,7 @@
   1.118          final DateList weekNoDates = getDateListInstance(dates);
   1.119          for (final Iterator i = dates.iterator(); i.hasNext();) {
   1.120              final Date date = (Date) i.next();
   1.121 -            final Calendar cal = Dates.getCalendarInstance(date);
   1.122 -            cal.setTime(date);
   1.123 +            final Calendar cal = getCalendarInstance(date, true);
   1.124              for (final Iterator j = getWeekNoList().iterator(); j.hasNext();) {
   1.125                  final Integer weekNo = (Integer) j.next();
   1.126                  cal.set(Calendar.WEEK_OF_YEAR, Dates.getAbsWeekNo(cal.getTime(), weekNo.intValue()));
   1.127 @@ -907,8 +925,7 @@
   1.128          final DateList yearDayDates = getDateListInstance(dates);
   1.129          for (final Iterator i = dates.iterator(); i.hasNext();) {
   1.130              final Date date = (Date) i.next();
   1.131 -            final Calendar cal = Dates.getCalendarInstance(date);
   1.132 -            cal.setTime(date);
   1.133 +            final Calendar cal = getCalendarInstance(date, true);
   1.134              for (final Iterator j = getYearDayList().iterator(); j.hasNext();) {
   1.135                  final Integer yearDay = (Integer) j.next();
   1.136                  cal.set(Calendar.DAY_OF_YEAR, Dates.getAbsYearDay(cal.getTime(), yearDay.intValue()));
   1.137 @@ -931,9 +948,7 @@
   1.138          final DateList monthDayDates = getDateListInstance(dates);
   1.139          for (final Iterator i = dates.iterator(); i.hasNext();) {
   1.140              final Date date = (Date) i.next();
   1.141 -            final Calendar cal = Dates.getCalendarInstance(date);
   1.142 -            cal.setLenient(false);
   1.143 -            cal.setTime(date);
   1.144 +            final Calendar cal = getCalendarInstance(date, false);
   1.145              for (final Iterator j = getMonthDayList().iterator(); j.hasNext();) {
   1.146                  final Integer monthDay = (Integer) j.next();
   1.147                  try {
   1.148 @@ -969,8 +984,7 @@
   1.149                  // if BYYEARDAY or BYMONTHDAY is specified filter existing
   1.150                  // list..
   1.151                  if (!getYearDayList().isEmpty() || !getMonthDayList().isEmpty()) {
   1.152 -                    final Calendar cal = Dates.getCalendarInstance(date);
   1.153 -                    cal.setTime(date);
   1.154 +                    final Calendar cal = getCalendarInstance(date, true);
   1.155                      if (weekDay.equals(WeekDay.getWeekDay(cal))) {
   1.156                          weekDayDates.add(date);
   1.157                      }
   1.158 @@ -991,15 +1005,7 @@
   1.159       * @return
   1.160       */
   1.161      private List getAbsWeekDays(final Date date, final Value type, final WeekDay weekDay) {
   1.162 -        final Calendar cal = Dates.getCalendarInstance(date);
   1.163 -        // default week start is Monday per RFC5545
   1.164 -        int calendarWeekStartDay = Calendar.MONDAY;
   1.165 -        if (weekStartDay != null) {
   1.166 -        	calendarWeekStartDay = WeekDay.getCalendarDay(new WeekDay(weekStartDay));
   1.167 -        }
   1.168 -        cal.setFirstDayOfWeek(calendarWeekStartDay);
   1.169 -        cal.setTime(date);
   1.170 -        
   1.171 +        final Calendar cal = getCalendarInstance(date, true);
   1.172          final DateList days = new DateList(type);
   1.173          if (date instanceof DateTime) {
   1.174              if (((DateTime) date).isUtc()) {
   1.175 @@ -1095,8 +1101,7 @@
   1.176          final DateList hourlyDates = getDateListInstance(dates);
   1.177          for (final Iterator i = dates.iterator(); i.hasNext();) {
   1.178              final Date date = (Date) i.next();
   1.179 -            final Calendar cal = Dates.getCalendarInstance(date);
   1.180 -            cal.setTime(date);
   1.181 +            final Calendar cal = getCalendarInstance(date, true);
   1.182              for (final Iterator j = getHourList().iterator(); j.hasNext();) {
   1.183                  final Integer hour = (Integer) j.next();
   1.184                  cal.set(Calendar.HOUR_OF_DAY, hour.intValue());
   1.185 @@ -1119,8 +1124,7 @@
   1.186          final DateList minutelyDates = getDateListInstance(dates);
   1.187          for (final Iterator i = dates.iterator(); i.hasNext();) {
   1.188              final Date date = (Date) i.next();
   1.189 -            final Calendar cal = Dates.getCalendarInstance(date);
   1.190 -            cal.setTime(date);
   1.191 +            final Calendar cal = getCalendarInstance(date, true);
   1.192              for (final Iterator j = getMinuteList().iterator(); j.hasNext();) {
   1.193                  final Integer minute = (Integer) j.next();
   1.194                  cal.set(Calendar.MINUTE, minute.intValue());
   1.195 @@ -1143,8 +1147,7 @@
   1.196          final DateList secondlyDates = getDateListInstance(dates);
   1.197          for (final Iterator i = dates.iterator(); i.hasNext();) {
   1.198              final Date date = (Date) i.next();
   1.199 -            final Calendar cal = Dates.getCalendarInstance(date);
   1.200 -            cal.setTime(date);
   1.201 +            final Calendar cal = getCalendarInstance(date, true);
   1.202              for (final Iterator j = getSecondList().iterator(); j.hasNext();) {
   1.203                  final Integer second = (Integer) j.next();
   1.204                  cal.set(Calendar.SECOND, second.intValue());
   1.205 @@ -1218,6 +1221,23 @@
   1.206      }
   1.207      
   1.208      /**
   1.209 +     * Construct a Calendar object and sets the time.
   1.210 +     * @param date
   1.211 +     * @param lenient 
   1.212 +     * @return 
   1.213 +     */
   1.214 +    private Calendar getCalendarInstance(final Date date, final boolean lenient) {
   1.215 +        Calendar cal = Dates.getCalendarInstance(date);
   1.216 +        // A week should have at least 4 days to be considered as such per RFC5545
   1.217 +        cal.setMinimalDaysInFirstWeek(4);
   1.218 +        cal.setFirstDayOfWeek(calendarWeekStartDay);
   1.219 +        cal.setLenient(lenient);     
   1.220 +        cal.setTime(date);
   1.221 +        
   1.222 +        return cal;
   1.223 +    }
   1.224 +    
   1.225 +    /**
   1.226       * @param stream
   1.227       * @throws IOException
   1.228       * @throws ClassNotFoundException
   1.229 @@ -1233,7 +1253,7 @@
   1.230       * @param origList
   1.231       * @return a new empty list.
   1.232       */
   1.233 -    private static final DateList getDateListInstance(final DateList origList) {
   1.234 +    private static DateList getDateListInstance(final DateList origList) {
   1.235          final DateList list = new DateList(origList.getType());
   1.236          if (origList.isUtc()) {
   1.237              list.setUtc(true);

mercurial