Recurrence rule in ICal4j

I'm trying to create an .ics file using ICal4j. But when I try to add a recurrence it fails, throwing a ValidationException:

net.fortuna.ical4j.model.ValidationException: Invalid property: RRULE at
        net.fortuna.ical4j.model.Calendar.validate(Calendar.java:297) at  
        net.fortuna.ical4j.model.Calendar.validate(Calendar.java:257) at 
        net.fortuna.ical4j.data.CalendarOutputter.output(CalendarOutputter.java:96) at 
        net.fortuna.ical4j.data.CalendarOutputter.output(CalendarOutputter.java:83)

My code to add the recurrence is:

Recur recur = new Recur(Recur.WEEKLY,null);
recur.setUntil( new DateTime(dateTo.getTime()) );

RRule rule = new RRule(recur);
cal.getProperties().add(rule);

Without this rule it works fine, but I want to add this event every monday until 12 December 2011 (the date returned by dateTo). Any ideas?

Answers


A reccurrence rule (RRULE) property must be added to a specific event (VEVENT) in the calendar, not the calendar itself. e.g.

myEvent.getProperties().add(rule);

Also if you want the event to occur on a Monday you should probably use a rule like this:

FREQ=WEEKLY;BYDAY=MO;UNTIL=<date>

This is off the top of my head, so best to check the RFC to be sure:

http://tools.ietf.org/html/rfc5545#section-3.3.10


Here is an example for my recurrence rule for same Weekly Recurrence Rule is

RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=MO;UNTIL=20161222T000000Z
RRULE:FREQ=MONTHLY;INTERVAL=<Every month/with some interval>;BYDAY=<Day of week>;UNTIL=<Until Date>

So as per this your rule will be like : "RRULE:FREQ=MONTHLY;INTERVAL=1;BYDAY=MO;UNTIL=20111212T000000Z"

Given is the code to create recurrence rule and dates

class CreateRule{

    static {
        weekMap.put(Short.valueOf("0"), "SU");
        weekMap.put(Short.valueOf("1"), "MO");
        weekMap.put(Short.valueOf("2"), "TU");
        weekMap.put(Short.valueOf("3"), "WE");
        weekMap.put(Short.valueOf("4"), "TH");
        weekMap.put(Short.valueOf("5"), "FR");
        weekMap.put(Short.valueOf("6"), "SA");
    }

    Short repeatCountMonthly = repeatCount != null ? repeatCount : 0;
    String weekDay = weekMap.get(<repeatMonthWeek>);
    //Create recurrence Rule    
    String monthlyRecurrenceRule = DateUtils.getMonthlyRecurrenceRule(repeatCountMonthly,endsNever,                             endsAfterOccurrences,endTime,repeatMonthDay,weekDay);
    //Create recurrence Dates
    Set<LocalDate> monthlyStartDates = CalendarUtils.getRecurrenceDates(monthlyRecurrenceRule,
                    LocalDate.fromDateFields(startDate));

}

Class will have methods to create Rule and generate Dates:

class DateUtils{

            public static String getMonthlyRecurrenceRule(Short interval,boolean endsNever,Integer occurrences, StringBuilder endTime,Short dayOfMonth,String dayOfWeek){
                StringBuilder monthlyRecurrenceRule = new StringBuilder("RRULE:FREQ=MONTHLY");

                if(interval!=null&&interval.intValue()>0)
                    monthlyRecurrenceRule.append(";INTERVAL=").append(interval.toString());

                if(dayOfMonth!=null && dayOfMonth>0)
                    monthlyRecurrenceRule.append(";BYMONTHDAY=").append(dayOfMonth.toString());
                else
                    monthlyRecurrenceRule.append(";BYDAY=").append(dayOfWeek);

                if(endsNever){
                    //set endtime as startdate+10 years
                    monthlyRecurrenceRule.append(";UNTIL=").append("20271231T090000Z");
                }
                else{
                    if(occurrences!=null&&occurrences.intValue()>0)
                        monthlyRecurrenceRule.append(";COUNT=").append(occurrences.toString());
                    else
                        monthlyRecurrenceRule.append(";UNTIL=").append(endTime.toString());
                }

                return monthlyRecurrenceRule.toString();
            }

            public static Set<LocalDate> getRecurrenceDates(String rRule,LocalDate startDate) throws ParseException{
                Set<LocalDate> recurrenceDates = new HashSet<LocalDate>();

                for (LocalDate date : LocalDateIteratorFactory.createLocalDateIterable(rRule, startDate, true)) {
                     recurrenceDates.add(date);
                    }

                return recurrenceDates;
            }   

        }

I had similar problem with this API. Unfortunately I do not have the code right now but I remember that problem was that some properties are "optional". There is an API that allows their registration. I'd recommend you to download the source code and check out what does method validate do. You will see that it verifies that the property is in collection (or map). Then just find that method that adds properties to this collection.

If you have troubles with achieving the source code just decompile the class files. I personally did this with this package. I used plugin to eclipse that decompiles every class that does not have associated source code: http://java.decompiler.free.fr/?q=jdeclipse

I am sorry that my answer is not concrete enough but I hope it is helpful anyway. Good luck.


Need Your Help

Is it guaranteed that std::vector each allocated memory with allocate function, will also deallocate at once, with single deallocate call?

c++ memory-management vector stl allocator

I'm writing custom allocator for std::vector, and want to know how std::vector uses specified allocator? May it allocate memory for 5 objects, and then deallocate memory partially, for example at f...

phpmyadmin error with sanitizing.lib.php

php mysql phpmyadmin

I am having a problem getting phpmyadmin to work correctly on my desktop. Every time I try running phpmyadmin, I get the following error: